[BZOJ2628][压位][Shift-And&Shift-Or]JZPSTR

来源:互联网 发布:网络lw代表什么意思 编辑:程序博客网 时间:2024/06/06 03:48

%%%Hillan

学了发Shift-And算法
再手打个Bitset就可以了

表示Bitset调了一天,调到最后查询出问题了……

#include <cstdio>#include <iostream>#include <string>#include <cstring>#include <algorithm>#define N 2000010using 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;}
0 0
原创粉丝点击