BZOJ4943 [NOI2017] 蚯蚓
題目描述
蚯蚓幼兒園有nn?只蚯蚓。幼兒園園長(zhǎng)神刀手為了管理方便,時(shí)常讓這些蚯蚓們列隊(duì)表演。
所有蚯蚓用從11?到nn?的連續(xù)正整數(shù)編號(hào)。每只蚯蚓的長(zhǎng)度可以用一個(gè)正整數(shù)表示,根據(jù)入園要求,所有蚯蚓的長(zhǎng)度都不超過66?。神刀手希望這些蚯蚓排成若干個(gè)隊(duì)伍,初始時(shí),每只蚯蚓各自排成一個(gè)僅有一只蚯蚓的隊(duì)伍,該蚯蚓既在隊(duì)首,也在隊(duì)尾。
神刀手將會(huì)依次進(jìn)行mm?次操作,每個(gè)操作都是以下三種操作中的一種:
給出ii?和jj?,令ii?號(hào)蚯蚓與jj?號(hào)蚯蚓所在的兩個(gè)隊(duì)伍合并為一個(gè)隊(duì)伍,具體來說,令jj?號(hào)蚯蚓緊挨在ii?號(hào)蚯蚓之后,其余蚯蚓保持隊(duì)伍的前后關(guān)系不變。
給出ii?,令ii?號(hào)蚯蚓與緊挨其后的一只蚯蚓分離為兩個(gè)隊(duì)伍,具體來說,在分離之后,ii?號(hào)蚯蚓在其中一個(gè)隊(duì)伍的隊(duì)尾,原本緊挨其后的那一只蚯蚓在另一個(gè)隊(duì)伍的隊(duì)首,其余蚯蚓保持隊(duì)伍的前后關(guān)系不變。
而f(t)f(t)?表示所有蚯蚓中,向后kk?數(shù)字串恰好為tt?的蚯蚓只數(shù)。
輸入輸出格式
輸入格式:
?
輸入文件的第一行有兩個(gè)正整數(shù)n,mn,m?,分別表示蚯蚓的只數(shù)與操作次數(shù)。
第二行包含nn?個(gè)不超過66?的正整數(shù),依次表示編號(hào)為1, 2, \dots , n1,2,…,n?的蚯蚓的長(zhǎng)度。
接下來mm?行,每行表示一個(gè)操作。每個(gè)操作的格式可以為:
-
1 i j?(1 \leqslant i, j \leqslant n)(1?i,j?n)?表示:令ii?號(hào)與jj?號(hào)蚯蚓所在的兩個(gè)隊(duì)伍合并為一個(gè)隊(duì)伍,新隊(duì)伍中,jj?號(hào)蚯蚓緊挨在ii?號(hào)蚯蚓之后。保證在此操作之前,ii?號(hào)蚯蚓在某個(gè)隊(duì)伍的隊(duì)尾,jj?號(hào)蚯蚓在某個(gè)隊(duì)伍的隊(duì)首,且兩只蚯蚓不在同一個(gè)隊(duì)伍中。
-
2 i?(1 \leqslant i \leqslant n)(1?i?n)?表示:令ii?號(hào)蚯蚓與緊挨其后一個(gè)蚯蚓分離為兩個(gè)隊(duì)伍。保證在此操作之前,ii?號(hào)蚯蚓不是某個(gè)隊(duì)伍的隊(duì)尾。
- 3 s k?(kk?為正整數(shù),ss?為一個(gè)長(zhǎng)度至少為kk?的數(shù)字串)表示:詢問ss?的每個(gè)長(zhǎng)度為kk?的子串tt?的f(t)f(t)?的乘積,對(duì)998244353998244353?取模的結(jié)果。f(t)f(t)?的定義見題目描述。
同一行輸入的相鄰兩個(gè)元素之間,用恰好一個(gè)空格隔開。
輸入文件可能較大,請(qǐng)不要使用過于緩慢的讀入方式。
?
輸出格式:
?
依次對(duì)于每個(gè)形如3 s k的操作,輸出一行,僅包含一個(gè)整數(shù),表示詢問的結(jié)果。
題目大意:
??? 一個(gè)初始全為單個(gè)元素的集合,支持合并,分裂,查詢s,k求出s所有長(zhǎng)度為k的子串在現(xiàn)有的序列中出現(xiàn)的次數(shù)的乘積。
題解:
???? ①用鏈表記錄nxt[],pre[]來模擬分裂,合并;
???? ②考慮到k<=50,意思就是我們只需要維護(hù)長(zhǎng)度在50以內(nèi)串,外加查詢其出現(xiàn)的次數(shù)。而分裂操作c并不多,意味著合并也并不多。暴力維護(hù)即可:每次合并分裂時(shí)枚舉跨過斷點(diǎn)前后50位以內(nèi)的串修改。
???? ③用hash散列表來修改和查詢,由于hash的模值比較大,無法開下所有v值,就可以將v類似于存邊存進(jìn)v%sz里,每次修改和查詢暴力枚舉一遍,復(fù)雜度幾乎為O(1)
?
1 #pragma GCC optimize(2) 2 #include<cstdio> 3 #include<iostream> 4 #include<cstring> 5 #define N 200010 6 #define M 11000000 7 #define base 1000000007 8 #define mod 998244353 9 #define ull unsigned long long 10 using namespace std; 11 int n,m,pre[N],nxt[N]; 12 char tmp[M],*P = tmp,*s,a[N]; 13 ull H[M],pw[M]; 14 char gc(){ 15 static char *p1,*p2,s[1000000]; 16 if(p1==p2) p2=(p1=s)+fread(s,1,1000000,stdin); 17 return(p1==p2)?EOF:*p1++; 18 } 19 int rd(){ 20 int x = 0,f = 1; char c = gc(); 21 while(c<'0'||c>'9') {if(c=='-') f = -1; c = gc();} 22 while(c>='0'&&c<='9') {x = x * 10 + c - '0'; c = gc();} 23 return x * f; 24 } 25 int rd(char *c){ 26 char *st = c; 27 do *c = gc(); while(*c<'0'||*c>'9'); 28 do *++c = gc(); while(*c>='0'&&*c<='9'); 29 *c = 0; 30 return c - st; 31 } 32 struct Edge{ull v; int nt,w;}; 33 const int sz = 1e7; 34 struct HASH{ 35 Edge E[sz + 1]; int o,hd[sz + 1]; 36 int& adde(ull v){ 37 E[++o] = (Edge){v,hd[v%sz],0}; hd[v%sz] = o; 38 return E[o].w; 39 } 40 int& operator [] (ull v){ 41 for(int i = hd[v%sz];i;i=E[i].nt) 42 if(E[i].v==v) return E[i].w; 43 return adde(v); 44 } 45 int val(ull v){ 46 for(int i = hd[v%sz];i;i=E[i].nt) 47 if(E[i].v==v) return E[i].w; 48 return 0; 49 } 50 }Hash; 51 void cal(int y,int x){ 52 static char S[N]; int len = 0,fg; 53 int st;for(st = y;pre[st]&&len<=50;st = pre[st],len++); fg = ++len; 54 int ed;for(ed = y;nxt[ed]&&len<=100;ed = nxt[ed],len++); 55 len = 0; //S[++len] = a[st]; 56 for(int i = st;nxt[i];i = nxt[i]) S[++len] = a[i]; 57 S[++len] = a[ed]; 58 for(int i = 1;i <= len;i++) H[i] = H[i - 1]*base + S[i]; 59 for(int i = fg;i <= len;i++) 60 for(int j = max(i - 50,0);j < fg - 1;j++){ 61 Hash[H[i] - H[j] * pw[i - j]]+=x; 62 } 63 } 64 int main() 65 { //freopen("mzoj1112.in","r",stdin); 66 //freopen("mzoj1112.out","w",stdout); 67 n = rd(); m = rd(); 68 for(int i = pw[0] = 1;i < M;i++) pw[i] = pw[i - 1] * base; 69 for(int i = 1;i <= n;i++) Hash[a[i] = rd() + '0']++; 70 for(int i = 1,typ,x,y,len,k;i <= m;i++){ 71 typ = rd(); 72 if(typ==1) { 73 x = rd(); y = rd(); 74 pre[y] = x; nxt[x] = y; 75 cal(y,1); 76 } 77 else if(typ==2){ 78 x = rd(); y = nxt[x]; 79 cal(y,-1); 80 pre[y] = nxt[x] = 0; 81 } 82 else{ 83 s = P; len = rd(s+1); P += len + 2; k = rd(); 84 ull ans = 1; 85 for(int i = 1;i <= len;i++){ 86 H[i] = H[i - 1]*base + s[i]; 87 if(i>=k) { 88 ull temp = H[i] - H[i - k] * pw[k]; 89 ans = ans * Hash.val(temp) % mod; 90 } 91 } 92 printf("%llu\n",ans); 93 } 94 } 95 return 0; 96 }//by tkys_Austin;?
?
?
?????
轉(zhuǎn)載于:https://www.cnblogs.com/Paul-Guderian/p/8579870.html
總結(jié)
以上是生活随笔為你收集整理的BZOJ4943 [NOI2017] 蚯蚓的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: vue中key的作用
- 下一篇: GVIM工具之gvim的配色方式