bzoj4943: [Noi2017]蚯蚓
hash表的技能点没有点。。。
作为一名在竞赛室苟延残喘的陪练有点说不过去吧。。。
需要注意的是如果要hash里面断链要考虑头和尾
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; typedef unsigned long long uLL; const int _=1e2; const int maxn=2*1e5+_; const int maxm=3*1e5+_; const int maxK=50+5; const int maxH=1.1*1e7; const int mins=1.5*1e7+_; int read() { int x=0,f=1; char ch=getchar(); while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();} return x*f; } void write(int x) { if(x>=10)write(x/10); putchar(x%10+'0'); } //-------------------------------------------------------------------------------- const uLL hbase=31; uLL hmi[maxK];//1 const uLL hm=10233333;//2 struct Hash { int num[mins];uLL d[mins],c[mins];//是向后多少数字串,第一步自然溢出的哈希值是多少 ,出现多少次 int len,first[maxH],last[maxH],nxt[mins]; void insert(int w,uLL k) { int x=k%hm; for(int i=first[x];i;i=nxt[i]) if(num[i]==w&&d[i]==k){c[i]++;return ;} int now=++len; if(last[x]==0)first[x]=last[x]=now; else nxt[last[x]]=now,last[x]=now; num[now]=w,d[now]=k,c[now]++; } void erase(int w,uLL k) { int x=k%hm; for(int p=0,i=first[x];i;p=i,i=nxt[i]) if(num[i]==w&&d[i]==k) { if(c[i]>1)c[i]--; else { if(p==0)first[x]=nxt[i]; else nxt[p]=nxt[i]; if(last[x]==i)last[x]=p; } return ; } } uLL getsum(int w,uLL k) { int x=k%hm; for(int i=first[x];i;i=nxt[i]) if(num[i]==w&&d[i]==k)return c[i]; return 0; } }H; //-------------------------------------------------------------------------------- const uLL mod=998244353; int a[maxn],L[maxn],R[maxn]; char ss[10001000]; int main() { freopen("a.in","r",stdin); freopen("a.out","w",stdout); hmi[0]=1;for(int i=1;i<=50;i++)hmi[i]=hmi[i-1]*hbase; int n=read(),Q=read(); for(int i=1;i<=n;i++) a[i]=read(),H.insert(1,a[i]); int op,x,y; while(Q--) { op=read(); if(op==1) { x=read(),y=read(); L[y]=x;R[x]=y; uLL uh=0,vh=0; for(int k=x,i=1;k&&i<50;k=L[k],i++) { uh=uh+a[k]*hmi[i-1]; vh=uh; for(int d=y,j=1;d&&i+j<=50;d=R[d],j++) { vh=vh*hbase+a[d]; H.insert(i+j,vh); } } } else if(op==2) { x=read(); y=R[x]; uLL uh=0,vh=0; for(int k=x,i=1;k&&i<50;k=L[k],i++) { uh=uh+a[k]*hmi[i-1]; vh=uh; for(int d=y,j=1;d&&i+j<=50;d=R[d],j++) { vh=vh*hbase+a[d]; H.erase(i+j,vh); } } R[x]=L[y]=0; } else { scanf("%s",ss+1);x=read(); int slen=strlen(ss+1); uLL ans=1,uh=0; for(int i=1;i<x;i++)uh=uh*hbase+ss[i]-'0'; for(int i=x;i<=slen;i++) { uh=uh*hbase+ss[i]-'0'; ans=(ans*H.getsum(x,uh))%mod; uh-=hmi[x-1]*(ss[i-x+1]-'0'); } printf("%llu\n",ans); } } return 0; }
pain and happy in the cruel world.