hdu 4787 GRE Words Revenge 在線AC自動機
阿新 • • 發佈:2017-07-15
def || uil 每次 ant iomanip tin san -1
"+w" : learn a word w
"?p": read a paragraph p, and count the number of learnt words. Formally speaking, count the number of substrings of p which is a learnt words.
Given the records of N days, help Coach Pang to find the count. For convenience, the characters occured in the words and paragraphs are only ‘0‘ and ‘1‘.
Input
The first line of the input file contains an integer T, which denotes the number of test cases. T test cases follow.
The first line of each test case contains an integer N (1 <= N <= 105), which is the number of days. Each of the following N lines contains either "+w" or "?p". Both p and w are 01-string in this problem.
Note that the input file has been encrypted. For each string occured, let L be the result of last "?" operation. The string given to you has been shifted L times (the shifted version of string s1 s2 ... sk is sks1s2 ... sk-1). You should decrypt the string to the original one before you process it. Note that L equals to 0 at the beginning of each test case.
The test data guarantees that for each test case, total length of the words does not exceed 105 and total length of the paragraphs does not exceed 5 * 106.
And for each "?" operation, output a line containing the result.
hdu 4787
GRE Words Revenge
Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 327680/327680 K (Java/Others)
Total Submission(s): 2505 Accepted Submission(s): 614
"+w"
"?p": read a paragraph p, and count the number of learnt words. Formally speaking, count the number of substrings of p which is a learnt words.
Given the records of N days, help Coach Pang to find the count. For convenience, the characters occured in the words and paragraphs are only ‘0‘ and ‘1‘.
The first line of each test case contains an integer N (1 <= N <= 105), which is the number of days. Each of the following N lines contains either "+w" or "?p". Both p and w are 01-string in this problem.
Note that the input file has been encrypted. For each string occured, let L be the result of last "?" operation. The string given to you has been shifted L times (the shifted version of string s1
The test data guarantees that for each test case, total length of the words does not exceed 105 and total length of the paragraphs does not exceed 5 * 106.
Output For each test case, first output a line "Case #x:", where x is the case number (starting from 1).
And for each "?" operation, output a line containing the result.
Sample Input 2 3 +01 +01 ?01001 3 +01 ?010 ?011
Sample Output Case #1: 2 Case #2: 1 0
Source 2013 Asia Chengdu Regional Contest
可持久化,也就是可以在線,邊詢問邊插入模式串,如果暴力每次插入後重建ac自動機,那麽復雜度就是O(N*N),的,可以想到用分塊(dalao是這麽叫的);建立一個大的自動機,一個小的自動機,小的自動機規模是sqrt(N),大的是N,每次插入時在小的buf 裏添加字串,重構自動機,當buf的規模超過sqrt(N)時,合並到大的自動機裏大的重建,復雜度為O(sqrt(N) * N);合並就是buf 與ac 的字典樹一起跑,如果ac裏沒有buf 的結點,就新建,然後權值|=buf.val[],(有節點也要| =,因為原來的不一定是單詞,但現在是了);
1 //2017-07-15 19:28:18 2 //2017-07-15 20:10:10 3 #include<algorithm> 4 #include<iostream> 5 #include<cstdlib> 6 #include<cstdio> 7 #include<cmath> 8 #include<map> 9 #include"set" 10 #include"queue" 11 #include"vector" 12 #include"iomanip" 13 #include"cstring" 14 #define inf 1<<29 15 #define ll long long 16 #define re register 17 #define il inline 18 #define rep(i,a,b) for(register int i=a;i<=b;++i) 19 #define file(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout); 20 using namespace std; 21 const int N=100010; 22 char tmp[5000100],s[5000100]; 23 struct ACAutomation{ 24 int f[N],ch[N][2],lst[N],sz; 25 int val[N]; 26 il void init() { 27 sz=0;ch[0][0]=ch[0][1]=0;lst[0]=0; 28 //val[0]=0; 29 } 30 il int newnode(){ 31 ++sz; 32 ch[sz][0]=ch[sz][1]=f[sz]=lst[sz]=0; 33 val[sz]=0;// 34 return sz; 35 } 36 il bool search(char *s,int len) { 37 re int t=0,c; 38 for(re int i=0;i<len;++i){ 39 c=s[i]-‘0‘; 40 if(!ch[t][c]) 41 return 0; 42 t=ch[t][c]; 43 } 44 return val[t]; 45 } 46 il void insert(char *s,int len){ 47 re int t=0,c; 48 for(re int i=0;i<len;++i){ 49 c=s[i]-‘0‘; 50 if(!ch[t][c]) 51 ch[t][c]=newnode(); 52 t=ch[t][c]; 53 } 54 val[t]=1; 55 } 56 il void build() { 57 queue<int> q; 58 for(re int i=0;i<2;++i){ 59 if(ch[0][i]) 60 q.push(ch[0][i]),f[ch[0][i]]=0,lst[ch[0][i]]=0; 61 } 62 re int r,v,u; 63 while(!q.empty()) { 64 r=q.front();q.pop(); 65 for(re int c=0;c<2;++c) { 66 u=ch[r][c]; 67 if(!u) continue; 68 q.push(u); 69 v=f[r]; 70 while(v&&!ch[v][c]) v=f[v]; 71 f[u]=ch[v][c]; 72 lst[u] = val[f[u]] ? f[u] : lst[f[u]]; 73 } 74 } 75 } 76 il int run(char *s,int len) { 77 re int t=0,ans=0,c; 78 for(re int i=0;i<len;++i) { 79 c=s[i]-‘0‘; 80 while(t&&!ch[t][c]) t=f[t]; 81 t=ch[t][c]; 82 for(re int p=t;p;p=lst[p]) 83 ans+=val[p]; 84 } 85 return ans; 86 } 87 }; 88 ACAutomation ac,buf; 89 90 inline int gi() { 91 re int res=0,f=1;re char ch=getchar(); 92 while((ch<‘0‘||ch>‘9‘)&&ch!=‘-‘) ch=getchar(); 93 if(ch==‘-‘) f=-1,ch=getchar(); 94 while(ch>=‘0‘&&ch<=‘9‘) res=res*10+ch-‘0‘,ch=getchar(); 95 return res*f; 96 } 97 il void bfs() { 98 queue<int> U,V; 99 U.push(0),V.push(0); 100 re int u,v,r1,r2; 101 while(!U.empty()) { 102 u=U.front(),v=V.front(); 103 U.pop(),V.pop(); 104 for(re int c=0;c<2;++c) 105 if(buf.ch[u][c]) { 106 r1=buf.ch[u][c],r2=ac.ch[v][c]; 107 if(!r2) { 108 ac.ch[v][c]=ac.newnode(); 109 } 110 r2=ac.ch[v][c]; 111 ac.val[r2]|=buf.val[r1]; 112 U.push(r1),V.push(r2); 113 } 114 } 115 } 116 il void go() { 117 bfs(); 118 buf.init(); 119 ac.build(); 120 } 121 int main(){ 122 file("Y"); 123 re int cas=gi(); 124 rep(tt,1,cas) { 125 printf("Case #%d:\n",tt); 126 ac.init(); 127 buf.init(); 128 re int n=gi(); 129 re int l=0; 130 rep(qyp,1,n) { 131 scanf("%s",tmp); 132 re int len=strlen(tmp); 133 re int p=l%(len-1); 134 s[0]=tmp[0]; 135 for(re int i=1;i<=p;i++) s[i+len-1-p]=tmp[i]; 136 for(re int i=1;i<len-p;++i) s[i]=tmp[i+p]; 137 if(s[0]==‘+‘) { 138 if(buf.search(s+1,len-1)||ac.search(s+1,len-1)) continue; 139 buf.insert(s+1,len-1); 140 buf.build(); 141 if(buf.sz>333) go(); 142 } 143 else { 144 l=ac.run(s+1,len-1) + buf.run(s+1,len-1); 145 printf("%d\n",l); 146 } 147 } 148 } 149 return 0; 150 }
hdu 4787 GRE Words Revenge 在線AC自動機