洛谷3823 [NOI2017] 蚯蚓排队 【哈希】
题目分析:
从$\sum|S|$入手。共考虑$\sum|S|$个$f(t)$。所以我们要一个对于每个$f(t)$在$O(1)$求解的算法。不难想到是哈希。
然后考虑分裂和合并操作。一次合并操作要考虑合并点之前的$O(k)$个点向后衔接的哈希值。共$O(k^2)$。看似超时实则不然。一个串最多$O(nk)$个哈希结果,所以均摊入手。
对于分裂和重合并不能均摊,所以多了一个$O(ck^2)$。
这题的合并和分裂只和合并点和分裂点有关,而这个信息是给出的,所以不需要额外使用数据结构维护结果。
时间复杂度$O(nk+mk+ck^2+\sum |s|)$
代码:
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<cstdlib> 5 using namespace std; 6 7 const int maxsz = 450; 8 const int maxn = 505000; 9 const int mod = 998244353; 10 const int hmod1 = 19260817; 11 const int hmod2 = 19491001; 12 13 int n,m,maxx; 14 int a[maxn],pts[maxn]; 15 int ans[maxn],Num,nouse[94],nuse[91]; 16 int hsh[hmod1+5],Nxt[maxn*25],real[maxn*25],val[maxn*25],hnum; 17 18 struct query{ int cas;string str; int l,r; }Q[maxn]; 19 20 int global = 0; 21 22 struct linktable{int pre[maxn>>1],nxt[maxn>>1];}T; 23 24 void in(int &x){ 25 char ch = getchar(); 26 while(ch > '9' || ch < '0') ch = getchar(); 27 while(ch <= '9' && ch >= '0') x = x*10+ch-'0',ch = getchar(); 28 } 29 30 void readstring(string &str){ 31 char ch = getchar(); 32 while(ch > '9' || ch < '0') ch =getchar(); 33 while(ch <= '9' && ch >= '0') str.push_back(ch),ch=getchar(); 34 } 35 36 void read(){ 37 in(n),in(m); 38 for(int i=1;i<=n;i++) {in(a[i]);} 39 for(int i=1;i<=m;i++){ 40 in(Q[i].cas); 41 if(Q[i].cas == 1) in(Q[i].l),in(Q[i].r); 42 else if(Q[i].cas == 2) in(Q[i].l); 43 else {readstring(Q[i].str),in(Q[i].l);Q[i].r = ++Num;maxx = max(maxx,Q[i].l);} 44 } 45 } 46 47 int imnum[60],numnum; 48 49 void Add_hash(int a1,int a2,int dr){ 50 int p1 = hsh[a1]; 51 while(true) { 52 if(real[p1] == a2) {val[p1]+=dr;return;} 53 if(Nxt[p1]) p1 = Nxt[p1]; 54 else break; 55 } 56 hnum++; if(p1) Nxt[p1] = hnum; 57 p1 = hnum; val[p1] = 1; real[p1] = a2; 58 if(!hsh[a1]) hsh[a1] = p1; 59 } 60 61 void buildnew(int lft,int rgt,int dr){ 62 numnum = 0;int now = lft; 63 while(true){ 64 if(numnum == maxx-1) break; 65 imnum[++numnum] = a[now]; 66 if(T.pre[now]) now = T.pre[now]; 67 else break; 68 } 69 now = rgt;long long um = 0,vm = 0; 70 for(int i=1;i<=numnum;i++){ 71 um = (1ll*nouse[i-1]*imnum[i]+um)%hmod1; 72 vm = (1ll*nuse[i-1]*imnum[i]+vm)%hmod2; 73 long long r1 = um,r2 = vm; 74 for(int j=i+1,jj=rgt;j<=maxx;j++){ 75 r1 = (r1*10+a[jj])%hmod1; r2 = (r2*10+a[jj])%hmod2; 76 Add_hash(r1,r2,dr); if(!T.nxt[jj])break; jj = T.nxt[jj]; 77 global++; 78 } 79 } 80 } 81 82 void link(int lft,int rgt){ 83 buildnew(lft,rgt,1); 84 T.nxt[lft] = rgt; T.pre[rgt] = lft; 85 } 86 87 void cut(int place){ 88 buildnew(place,T.nxt[place],-1); 89 T.pre[T.nxt[place]] = 0; T.nxt[place] = 0; 90 } 91 92 int COUNT(int alpha,int beta){ 93 int fw = 0; 94 for(int i=hsh[alpha];i;i=Nxt[i]){ 95 if(real[i] != beta) continue; 96 fw += val[i]; 97 } 98 return fw; 99 } 100 101 void work(){ 102 for(int i=1;i<=n;i++) nouse[a[i]]++; 103 for(int i=1;i<=m;i++){ 104 if(Q[i].cas != 3 || Q[i].l != 1) continue; 105 int fw = 1; for(int j=0;j<Q[i].str.length();j++){fw = (1ll*fw*nouse[Q[i].str[j]-'0'])%mod;} 106 ans[Q[i].r] = fw; 107 } 108 memset(nouse,0,sizeof(nouse)); nouse[0] = 1;nuse[0] = 1; 109 for(int i=1;i<=55;i++) nouse[i] = (nouse[i-1]*10ll)%hmod1,nuse[i] = (nuse[i-1]*10ll)%hmod2; 110 111 for(int i=1;i<=m;i++){ 112 if(Q[i].cas == 1) link(Q[i].l,Q[i].r); 113 else if(Q[i].cas == 2) cut(Q[i].l); 114 else{ 115 if(Q[i].l == 1) continue; 116 int fw = 1;long long hres1=0,hres2 = 0; 117 for(int j=0;j<Q[i].l;j++){ 118 hres1 = hres1*10+Q[i].str[j]-'0'; 119 hres2 = hres2*10+Q[i].str[j]-'0'; 120 hres1 %= hmod1; hres2 %= hmod2; 121 } 122 fw = (1ll*fw*COUNT(hres1,hres2))%mod; 123 for(int j=Q[i].l;j<Q[i].str.length();j++){ 124 hres1 -= ((Q[i].str[j-Q[i].l]-'0')*nouse[Q[i].l-1])%hmod1; 125 hres1 += hmod1; hres1 %= hmod1; 126 hres2 -= ((Q[i].str[j-Q[i].l]-'0')*nuse[Q[i].l-1])%hmod2; 127 hres2 += hmod2; hres2 %= hmod2; 128 hres1 = (hres1*10+Q[i].str[j]-'0');hres1 %= hmod1; 129 hres2 = (hres2*10+Q[i].str[j]-'0');hres2 %= hmod2; 130 fw = (1ll*fw*COUNT(hres1,hres2))%mod; 131 } 132 ans[Q[i].r] = fw; 133 } 134 } 135 for(int i=1;i<=Num;i++) printf("%d\n",ans[i]); 136 } 137 138 int main(){ 139 read(); 140 work(); 141 return 0; 142 }