%%%Hillan
学了发Shift-And算法
再手打个Bitset就可以了
表示Bitset调了一天,调到最后查询出问题了……
#include <cstdio>
#include <iostream>
#include <string>
#include <cstring>
#include <algorithm>
#define N 2000010
using namespace std;
typedef unsigned int uint;
int cou[1<<17];
inline int Count(uint a){
return cou[a&65535]+cou[a>>16];
}
struct Bitset{
uint A[N/32+15]; int len;
Bitset(){ len=0; memset(A,0,sizeof(A)); }
void set0(int B,int W){ A[B]&=~(1U<<W); }
void set1(int B,int W){ A[B]|=(1U<<W); }
void shr(int x,int y){
int E=len>>5,B=x>>5,S=y>>5,w=y&31,v=(32-w)&31;
A[E+S+1]=0;
for(int i=E;i>B;i--)
A[i+S+1]|=v?A[i]>>v:0,A[i+S]=A[i]<<w;
for(int i=(B<<5)+31;i>=x;i--)
insert(i+y,(A[i>>5]>>(i&31))&1);
len+=y;
}
void shl(int x,int y){
int E=len>>5,B=x>>5,S=y>>5,w=y&31,v=(32-w)&31;
len-=y;
for(int i=x;i<=(B<<5)+31;i++)
insert(i,(A[i+y>>5]>>((i+y)&31))&1);
for(int i=B+1;i<=E;i++)
A[i]=A[i+S]>>w,A[i]|=v?A[i+S+1]<<v:0;
}
void insert(int x,int y){
int B=x>>5,w=x&31;
if(y) set1(B,w); else set0(B,w);
}
void And(int x,int y,Bitset B){
x>>=5; y>>=5;
for(int i=x;i<=y;i++) A[i]&=B.A[i];
}
Bitset sub(int a,int b){
a>>=5; b>>=5;
Bitset c; c.len=len;
for(int i=a;i<=b;i++) c.A[i]=A[i];
return c;
}
int count(int l,int r){
int S=l>>5,E=r>>5,R=0;
l&=31; r&=31;
if(S==E) return Count((A[S]>>l)&((1<<r-l+1)-1));
for(int i=S+1;i<=E-1;i++) R+=Count(A[i]);
R+=Count(A[S]>>l)+Count(A[E]<<31-r);
return R;
}
}f[10],S;
int n,op,l,r,length,x,y;
int inc[1000010];
inline void First(){
for(int i=1;i<(1<<16);i++)
cou[i]=cou[i>>1]+(i&1);
}
inline char nc(){
static char buf[100000],*p1=buf,*p2=buf;
return p1==p2?((p2=(p1=buf)+fread(buf,1,100000,stdin))==p1?EOF:*p1++):*p1++;
}
inline void reaD(int &x){
char c=nc(); x=0;
for(;c>57||c<48;c=nc());for(;c>=48&&c<=57;x=x*10+c-48,c=nc());
}
inline void reaD(int *x){
char c=nc(); length=0;
for(;c>57||c<48;c=nc());for(;c>=48&&c<=57;x[++length]=c-48,c=nc());
}
int main(){
First(); reaD(n);
while(n--){
reaD(op);
if(op==0){
reaD(x); reaD(inc);
for(int i=0;i<10;i++) f[i].shr(x,length);
for(int i=1;i<=length;i++)
for(int j=0;j<10;j++)
if(j==inc[i]) f[j].insert(i+x-1,1);
else f[j].insert(i+x-1,0);
}
else if(op==1){
reaD(x); reaD(y); y-=x;
if(!y) continue;
for(int i=0;i<10;i++) f[i].shl(x,y);
}
else{
reaD(x); reaD(y); reaD(inc);
if(y-x<length){ puts("0"); continue; }
S=f[inc[1]].sub(x,y);
for(int i=2;i<=length;i++){
S.shr(x,1);
S.And(x,y,f[inc[i]]);
}
printf("%d\n",S.count(x+length-1,y-1));
}
}
return 0;
}