bzoj1273: [BeiJingWc2008]序列

来源:互联网 发布:淘宝贷款逾期最坏结果 编辑:程序博客网 时间:2024/06/06 17:03

传送门
首先观察到是全局加,可用变量X表示。
然后对于依次询问,大力转移一法询问范围。
然后随便用一下线段树就OK辣。

#include<cmath>#include<cstdio>#include<cstdlib>#include<cstring>#include<iostream>#include<algorithm>#define N 65535using namespace std;char s[10];int n,m,x,t,X,l,r,mo;int v[16][270000];long long ans; void change(int K,int k,int l,int r,int p){    v[K][k]++;    if (l==r) return;    int mid=(l+r)/2;    if (p<=mid) change(K,k*2,l,mid,p);    else change(K,k*2+1,mid+1,r,p);}int ask(int K,int k,int l,int r,int x,int y){    if (l==x&&r==y) return v[K][k];    int mid=(l+r)/2;    if (y<=mid) return ask(K,k*2,l,mid,x,y);    if (x>mid) return ask(K,k*2+1,mid+1,r,x,y);    return ask(K,k*2,l,mid,x,mid)+ask(K,k*2+1,mid+1,r,mid+1,y);}int main(){    scanf("%d%d",&n,&m);    while (n--){        scanf("%d",&x);        t=0;        for (int i=0;i<16;i++){            t+=x&(1<<i);            change(i,1,0,N,t);        }    }    while (m--){        scanf("%s",s);        if (s[0]=='A'){            scanf("%d",&x);            X+=x;        }        if (s[0]=='Q'){            scanf("%d",&x);            if (x>=16){                puts("0");                continue;            }            l=1<<x; r=l*2-1; mo=r+1;            l=(l-X%mo+mo)%mo;            r=(r-X%mo+mo)%mo;            if (l<=r) ans+=ask(x,1,0,N,l,r);            else ans+=ask(x,1,0,N,l,N)+ask(x,1,0,N,0,r);        }    }    printf("%lld",ans);}
原创粉丝点击