首页 > 代码库 > 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