首页 > 代码库 > BZOJ2628 : JZPSTR
BZOJ2628 : JZPSTR
考虑shift-and算法,那么只需要维护10个bitset即可,$f[i][j]$表示字符串$S$的第$j$位是否是字符$i$。
对于修改操作,直接暴力修改10个bitset即可,时间复杂度$O(\frac{|S|\sum}{32})$。
对于查询$T$在$S$中所有出现的位置,有$ans=ans<<1\ and\ f[T[i]]$,时间复杂度$O(\frac{|S||T|}{32})$。
#include<cstdio>#include<cstring>typedef unsigned int U;const int N=1000010;int T,op,x,y,i,j,n,cb,m,g[65536];char s[N];inline int popcount(U x){return g[x>>16]+g[x&65535];}struct BIT{ U v[N/32+5]; void clr(){for(int i=0;i<=cb;i++)v[i]=0;} U get(int x){return v[x>>5]>>(x&31)&1;} void set(int x,U y){if((v[x>>5]>>(x&31)&1)^y)v[x>>5]^=1U<<(x&31);} void flip(int x){v[x>>5]^=1U<<(x&31);} void shr(int x,int y){ int A=y>>5,B=y&31,C=(32-B)&31,D=x>>5; v[cb+A+1]=0; for(int i=cb;i>D;i--){ if(C)v[i+A+1]|=v[i]>>C; v[i+A]=v[i]<<B; } for(int i=(D<<5)+31;i>=x;i--)set(i+y,get(i)); } void shl(int x,int y){ int A=y>>5,B=y&31,C=(32-B)&31,D=x>>5,E=(D<<5)+31; for(int i=x;i<=E;i++)set(i,get(i+y)); for(int i=D+1;i<=cb;i++){ v[i]=v[i+A]>>B; if(C)v[i]|=v[i+A+1]<<C; } } void copy(int x,int y,const BIT&p){for(int i=x;i<=y;i++)v[i]=p.v[i];} void And(int x,int y,const BIT&p){for(int i=x;i<=y;i++)v[i]&=p.v[i];} void shift(int x,int y){ for(int i=y;i>=x;i--){ v[i]<<=1; if(i&&(v[i-1]>>31&1))v[i]|=1; } } int count(int x,int y){ int A=x>>5,B=y>>5,C,ret=0; if(A==B){ for(int i=x;i<=y;i++)if(v[A]>>(i&31)&1)ret++; return ret; } for(int i=A+1;i<B;i++)ret+=popcount(v[i]); C=(A<<5)+31; for(int i=x;i<=C;i++)if(v[A]>>(i&31)&1)ret++; C=B<<5; for(int i=C;i<=y;i++)if(v[B]>>(i&31)&1)ret++; return ret; }}f[10],S;inline void getstr(){ scanf("%s",s); m=strlen(s); for(i=0;i<m;i++)s[i]-=‘0‘;}inline void ins(int x){ for(i=0;i<10;i++)f[i].shr(x,m); for(i=0;i<10;i++)for(j=0;j<m;j++)f[i].set(x+j,s[j]==i); n+=m; cb=n>>5;}inline void del(int x,int y){ if(x==y)return; n-=y-x; cb=n>>5; for(i=0;i<10;i++)f[i].shl(x,y-x);}inline int ask(int x,int y){ if(y-x<m)return 0; y--; int A=x>>5,B=y>>5; S.copy(A,B,f[s[0]]); for(i=1;i<m;i++)S.shift(A,B),S.And(A,B,f[s[i]]); return S.count(x+m-1,y);}int main(){ for(i=1;i<65536;i++)g[i]=g[i>>1]+(i&1); scanf("%d",&T); while(T--){ scanf("%d%d",&op,&x); if(op==0){ getstr(); ins(x); }else if(op==1){ scanf("%d",&y); del(x,y); }else{ scanf("%d",&y); getstr(); printf("%d\n",ask(x,y)); } } return 0;}
BZOJ2628 : JZPSTR
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。