BZOJ4627 [BeiJing2016]回转寿司

来源:互联网 发布:js 多维数组转json 编辑:程序博客网 时间:2024/06/02 13:45

求前缀和,相当于对于每个i求1<=j<i,L<=s[i]-s[j]<=R的个数然后加起来,用权值线段树搞就好了

#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<cmath>#include<algorithm>#include<iomanip>#include<ctime>#include<vector>#include<stack>#include<set>#include<bitset>#include<map>#include<queue>using namespace std;#define MAXN 100010#define MAXM 8000010#define MOD 1000000007#define INF 10000000000ll#define eps 1e-8#define ll long longint n,L,R;int siz[MAXM],son[MAXM][2];int tot;int rt;void change(int &x,ll y,ll z,ll p){if(!x){x=++tot;}siz[x]++;if(y==z){return ;}ll mid=y+z>>1;if(p<=mid){change(son[x][0],y,mid,p);}else if(p>mid){change(son[x][1],mid+1,z,p);}}int ask(int x,ll y,ll z,ll l,ll r){if(!x){return 0;}if(y==l&&z==r){return siz[x];}ll mid=y+z>>1;if(r<=mid){return ask(son[x][0],y,mid,l,r);}else if(l>mid){return ask(son[x][1],mid+1,z,l,r);}else{return ask(son[x][0],y,mid,l,mid)+ask(son[x][1],mid+1,z,mid+1,r);}}ll ans;int main(){int i,x;ll s=0;scanf("%d%d%d",&n,&L,&R);for(i=1;i<=n;i++){scanf("%d",&x);change(rt,-INF,INF,s);s+=x;ans+=ask(rt,-INF,INF,max(-INF,s-R),min(INF,s-L));}printf("%lld\n",ans);return 0;}/**/


0 0