4.9 每日一题题解

Eugene and an array

涉及知识点:

  • 双指针/前缀和

solution:

  • \(题意简单概括为,给出数组a,让你找到所有的b数组,b数组需要满足两个条件:\)
  • \(条件1,b数组是a数组的子数组(要求连续)\)
  • \(条件2,b数组的子数组(要求连续)之和不等于0\)
  • \(n = 1e5 , 暴力不可解\)
  • \(子数组因为是连续的,假设[1,x]的和为a,[1,y]的和也为a,那就说明[x+1,y]这段子数组和为0\)
  • $根据这个特点,固定右端点y,我们只能取左端点为x+2,x+3,x+4......y $
  • \(因为如果取左端点为x+1或者更小,[x+1,y]这段子数组和为0,不满足条件\)
  • \(所以做法就是:O(n)枚举每一个右端点,用map存一下前缀和,记录一下左端点的最大值,更新答案\)

std:

#include <bits/stdc++.h>
using namespace std;
#define ll long long 
const int maxn = 200005;
ll a[maxn],pre[maxn];
int main()
{
    int n , l = 0;
    ll ans = 0;
    cin>>n;
    for(int i=1;i<=n;i++)cin>>a[i],pre[i] = pre[i-1] + a[i];
    map<ll , int > mp;
    mp[0] = 0;
    for(int i=1;i<=n;i++){
        if(mp[pre[i]] || pre[i] == 0)
            l = max(l , mp[pre[i]] + 1);
        ans += 1ll*(i - l);
        mp[pre[i]] = i;
    }
    cout<<ans<<endl;
    return 0;
}
posted @ 2020-04-09 12:53  QFNU-ACM  阅读(141)  评论(0编辑  收藏  举报