【CF1042D】Petya and Array
阿新 • • 發佈:2019-03-02
lin 優化 題目 ++ namespace oid hup name include
題目大意:給定一個 N 個數組成的序列,給定一個 T,求有多少個區間滿足\(\sum_{i=l}^ra[i]<T\)。
題解:區間和問題可以用前綴和優化,即:求有多少個區間滿足\(sum[r]-sum[l-1]<T\) 成立。移項得:\(sum[l-1]>sum[r]-T\),即:維護 sum 數組中的每個數,前面有多少數滿足以上關系式。直接用平衡樹維護即可。
代碼如下
#include <bits/stdc++.h> using namespace std; const int maxn=2e5+10; struct node{ #define ls(x) t[x].lc #define rs(x) t[x].rc int lc,rc,rd,size,cnt; long long val; }t[maxn]; int tot,root; inline void pushup(int p){ t[p].size=t[ls(p)].size+t[rs(p)].size+t[p].cnt; } inline int newnode(long long val){ ++tot,t[tot].val=val,t[tot].rd=rand(),t[tot].cnt=t[tot].size=1; return tot; } inline void zig(int &p){ int lson=ls(p); ls(p)=rs(lson),rs(lson)=p,p=lson; pushup(rs(p)),pushup(p); } inline void zag(int &p){ int rson=rs(p); rs(p)=ls(rson),ls(rson)=p,p=rson; pushup(ls(p)),pushup(p); } void insert(int &p,long long val){ if(!p)p=newnode(val); else if(t[p].val==val)++t[p].size,++t[p].cnt; else if(val<t[p].val){ ++t[p].size,insert(ls(p),val); if(t[ls(p)].rd>t[p].rd)zig(p); }else{ ++t[p].size,insert(rs(p),val); if(t[rs(p)].rd>t[p].rd)zag(p); } } int query(int p,long long val){ if(!p)return 0; else if(t[p].val>val)return t[p].cnt+t[rs(p)].size+query(ls(p),val); else return query(rs(p),val); } int n; long long m,ans,sum[maxn]; void read_and_parse(){ scanf("%d%lld",&n,&m); for(int i=1;i<=n;i++)scanf("%lld",&sum[i]),sum[i]+=sum[i-1]; } void solve(){ insert(root,0); for(int i=1;i<=n;i++){ ans+=query(root,sum[i]-m); insert(root,sum[i]); } printf("%lld\n",ans); } int main(){ read_and_parse(); solve(); return 0; }
【CF1042D】Petya and Array