日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

BZOJ4943 [NOI2017] 蚯蚓

發布時間:2025/7/14 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 BZOJ4943 [NOI2017] 蚯蚓 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目描述

蚯蚓幼兒園有nn?只蚯蚓。幼兒園園長神刀手為了管理方便,時常讓這些蚯蚓們列隊表演。

所有蚯蚓用從11?nn?的連續正整數編號。每只蚯蚓的長度可以用一個正整數表示,根據入園要求,所有蚯蚓的長度都不超過66?。神刀手希望這些蚯蚓排成若干個隊伍,初始時,每只蚯蚓各自排成一個僅有一只蚯蚓的隊伍,該蚯蚓既在隊首,也在隊尾。

神刀手將會依次進行mm?次操作,每個操作都是以下三種操作中的一種:

  • 給出ii?jj?,令ii?號蚯蚓與jj?號蚯蚓所在的兩個隊伍合并為一個隊伍,具體來說,令jj?號蚯蚓緊挨在ii?號蚯蚓之后,其余蚯蚓保持隊伍的前后關系不變。

  • 給出ii?,令ii?號蚯蚓與緊挨其后的一只蚯蚓分離為兩個隊伍,具體來說,在分離之后,ii?號蚯蚓在其中一個隊伍的隊尾,原本緊挨其后的那一只蚯蚓在另一個隊伍的隊首,其余蚯蚓保持隊伍的前后關系不變。

  • 給出一個正整數kk?和一個長度至少為kk?的數字串ss?,對于ss?的每個長度為kk?的連續子串tt?(這樣的子串共有|s| - k + 1s?k+1?個,其中|s|s?ss?的長度),定義函數f(t)f(t)?,詢問所有這些f(t)f(t)?乘積998244353998244353?取模后的結果。其中f(t)f(t)?的定義如下: 對于當前的蚯蚓隊伍,定義某個蚯蚓的向后kk?數字串為:從該蚯蚓出發,沿隊伍的向后方向,尋找最近的kk?只蚯蚓(包括其自身),將這些蚯蚓的長度視作字符連接而成的數字串;如果這樣找到的蚯蚓不足kk只,則其沒有向后kk?數字串。例如蚯蚓的隊伍為1010?號蚯蚓在隊首,其后是2222?號蚯蚓,其后是33?號蚯蚓(為隊尾),這些蚯蚓的長度分別為44?、55?、66?,則1010?號蚯蚓的向后33?數字串?4562222?號蚯蚓沒有向后33?數字串,但其向后22?數字串56,其向后11?數字串5。
  • f(t)f(t)?表示所有蚯蚓中,向后kk?數字串恰好為tt?的蚯蚓只數。

    輸入輸出格式

    輸入格式:

    ?

    輸入文件的第一行有兩個正整數n,mn,m?,分別表示蚯蚓的只數與操作次數。

    第二行包含nn?個不超過66?的正整數,依次表示編號為1, 2, \dots , n1,2,,n?的蚯蚓的長度。

    接下來mm?行,每行表示一個操作。每個操作的格式可以為:

    • 1 i j?(1 \leqslant i, j \leqslant n)(1?i,j?n)?表示:令ii?號與jj?號蚯蚓所在的兩個隊伍合并為一個隊伍,新隊伍中,jj?號蚯蚓緊挨在ii?號蚯蚓之后。保證在此操作之前,ii?號蚯蚓在某個隊伍的隊尾,jj?號蚯蚓在某個隊伍的隊首,且兩只蚯蚓不在同一個隊伍中。

    • 2 i?(1 \leqslant i \leqslant n)(1?i?n)?表示:令ii?號蚯蚓與緊挨其后一個蚯蚓分離為兩個隊伍。保證在此操作之前,ii?號蚯蚓不是某個隊伍的隊尾。

    • 3 s k?kk?為正整數,ss?為一個長度至少為kk?的數字串)表示:詢問ss?的每個長度為kk?的子串tt?f(t)f(t)?的乘積,對998244353998244353?取模的結果。f(t)f(t)?的定義見題目描述。

    同一行輸入的相鄰兩個元素之間,用恰好一個空格隔開。

    輸入文件可能較大,請不要使用過于緩慢的讀入方式。

    ?

    輸出格式:

    ?

    依次對于每個形如3 s k的操作,輸出一行,僅包含一個整數,表示詢問的結果。

    題目大意:

    ??? 一個初始全為單個元素的集合,支持合并,分裂,查詢s,k求出s所有長度為k的子串在現有的序列中出現的次數的乘積。

    題解:

    ???? ①用鏈表記錄nxt[],pre[]來模擬分裂,合并;

    ???? ②考慮到k<=50,意思就是我們只需要維護長度在50以內串,外加查詢其出現的次數。而分裂操作c并不多,意味著合并也并不多。暴力維護即可:每次合并分裂時枚舉跨過斷點前后50位以內的串修改。

    ???? ③用hash散列表來修改和查詢,由于hash的模值比較大,無法開下所有v值,就可以將v類似于存邊存進v%sz里,每次修改和查詢暴力枚舉一遍,復雜度幾乎為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;

    ?

    ?

    ?

    ?????

    轉載于:https://www.cnblogs.com/Paul-Guderian/p/8579870.html

    總結

    以上是生活随笔為你收集整理的BZOJ4943 [NOI2017] 蚯蚓的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。