問題の意味
長さn ARの配列を指定(N <= 2E5)
この配列ARはサブアレイがどのくらいあるか尋ね良い配列
サブアレイは次のように定義されます。
0により、または配列要素の全てを削除することによって、続いて省略配列又は要素0の全ての前部は、元の配列の部分配列から得られます
グッド配列は次のように定義されます
各アレイのサブアレイBを満たす合計{B}≠0
配列は良い配列です
そのABS([I])を確保するため、各アレイ要素<= 1E9
問題解決のためのアイデア
我々は、サブアレイとBRを発見したと仮定0
他のサブ配列はBRが含まれている限り、これらのサブアレイは良い配列と呼ばれることができません
我々は要素ARを扱っているので、[i]は、ちょうど見て右の境界のためのAR [i]の時に私は=サブアレイ、R
Iので、この時、左マージンLで、それを含むようにサブアレイおよび0の後に停止し、開始位置から左探し
次いでRLれる[i]はArには、右境界でのウェルアレイ([R、R]、[L、R]を含んでいない含む)数
限り、この間隔でIに記録ケース1として、及びサブアレイ0〜最大左の境界MAXLに
たびに答えプラスI-MAXL
そして、サブアレイ0に対して決定され、そしてそこにいるかどうかは、プレフィックス判断記録されました
例えば、[1、X]、及び、[1、y]のように、または、その番組[X + 1、y]が0であり、この部分配列であります
プレフィックスと別個の分布が、記憶のために使用するマップ/ unordered_mapそう
全体の時間の複雑さがあるO(nlogn)
プログラム
既定値では表示されませんでしたキーマップが0である、共通の接頭辞があったかどうかを決定するために使用することができ、
それ以外の場合は最初のサブアレイ1と0から始まる要素の始まりは、プレフィックスと0を記録するための時間を持っていなかったことを注意は、判断されることはありません
MAXLを行わない場合は、この場合には大きい方、フォームのサブアレイ0および包含関係の2つ(例えば11-1-1、[1,4]及び[2,3]、0)が存在し得るためそうでなければ可能性があるため、私は4小MAXL = 1に代入値、およびアイデアに行う= MAXL 2は、一致しません
最後に、長整数に注意を払います
(186ms / 1500ms)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
map<ll,int> mp;
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
int n;
ll ar,sum=0,ans=0,maxL=1;
cin>>n;
mp[0]=1;//初始前缀和为0
for(int i=2;i<=n+1;i++)
{
cin>>ar;
sum+=ar;
if(mp[sum]!=0)
maxL=max(maxL,ll(mp[sum]+1)); //记得取大(否则wa8……)
ans+=i-maxL;//以i为右边界,满足题意的个数
mp[sum]=i;
}
cout<<ans<<'\n';
return 0;
}