codeforces 1042d//Petya and Array// Codeforces Round #510 (Div. 2)
题意:给出一个数组,求其中和小于t的区间数。
先计算前缀和数组sum[i]。对当前的sum[i],查询树状数组中有几个比(sum[i]-t)大的数,那么用sum[i]减它就是一个合法区间。再将当前的sum[i]加入树状数组。
//#pragma comment(linker,"/STACK:1024000000,1024000000") #include<iostream> #include<cstdio> #include<string> #include<cstring> #include<vector> #include<cmath> #include<queue> #include<stack> #include<map> #include<set> #include<algorithm> #include <stack> #include <bitset> #include <iomanip> using namespace std; const int SZ=2000010,INF=0x7FFFFFFF; typedef long long lon; lon n,t; lon arr[SZ],sum[SZ],tot[SZ]; vector<lon> ls; lon lowbit(lon x) { return x&(-x); } void add(lon x) { for(;x<=n+1;x+=lowbit(x)) { ++tot[x]; } } lon getsum(lon x) { lon res=0; for(;x;x-=lowbit(x)) { res+=tot[x]; } return res; } void init() { cin>>n>>t; for(lon i=1;i<=n;++i)cin>>arr[i],sum[i]=sum[i-1]+arr[i]; ls.push_back(0); for(lon i=1;i<=n;++i) { ls.push_back(sum[i]); } sort(ls.begin(),ls.end()); } lon work() { lon res=0; lon pos=lower_bound(ls.begin(),ls.end(),0)-ls.begin()+1; add(pos); //cout<<" "<<pos<<endl; for(lon i=1;i<=n;++i) { pos=upper_bound(ls.begin(),ls.end(),sum[i]-t)-ls.begin(); lon tmp=i-getsum(pos); //cout<<tmp<<" "<<pos<<endl; res+=tmp; lon cur=lower_bound(ls.begin(),ls.end(),sum[i])-ls.begin()+1; add(cur); //if(sum[i]<t)++res; } return res; } int main() { std::ios::sync_with_stdio(0); //freopen("d:\\1.txt","r",stdin); //for(;scanf("%d",&n)!=EOF;) { init(); cout<<work()<<endl; } return 0; }