hdu_4787_GRE Words Revenge(在线AC自动机)

题目链接:hdu_4787_GRE Words Revenge

题意:

总共有n个操作,2种操作。每行读入一个字符串。

1.如果字符串以+开头,此为单词(即模式串,不考虑重复)

2.如果字符串以?开头,此为文章(即文本串,查询在此之前的单词在文本串中出现的次数)

题解:

强制在线的AC自动机

贴个大牛的详细题解http://blog.csdn.net/no__stop/article/details/16823479

这样的带合并操作的AC自动机用第二种建树的方式比较方便

 1 #include<bits/stdc++.h>
 2 #define F(i,a,b) for(int i=a;i<=b;i++)
 3 using namespace std;
 4
 5 const int AC_N=1e5+7,tyn=2,M=5e6+10;//数量乘串长,类型数
 6 struct AC_automation{
 7     int tr[AC_N][tyn],cnt[AC_N],Q[AC_N],fail[AC_N],tot;
 8     void nw(){cnt[++tot]=0;memset(tr[tot],-1,sizeof(tr[tot]));}
 9     void init(){tot=-1,fail[0]=-1,nw();}
10     void insert(char *s,int x=0){
11         for(int i=0,w;s[i];x=tr[x][w],i++)
12             if(tr[x][w=s[i]-‘0‘]==-1)nw(),tr[x][w]=tot;
13         cnt[x]=1;//串尾标记
14     }
15     void build(int head=1,int tail=0){
16         F(i,0,1)if(~tr[0][i])Q[++tail]=tr[0][i],fail[tr[0][i]]=0;
17         while(head<=tail){
18             for(int i=0,x=Q[head++],p=-1;i<tyn;i++)if(~tr[x][i]){
19                 for(p=fail[x],fail[tr[x][i]]=0;~p;p=fail[p])
20                     if(~tr[p][i]){fail[tr[x][i]]=tr[p][i];break;}
21                 Q[++tail]=tr[x][i];
22             }
23         }
24     }
25     int ask(char *s,int ans=0){
26         for(int w,i=0,x=0,j;s[i];i++){
27             while(tr[x][w=s[i]-‘0‘]==-1&&x)x=fail[x];
28             x=tr[x][w],x=(~x)?x:0,j=x;
29             while(j){if(cnt[j])ans++;j=fail[j];}
30         }
31         return ans;
32     }
33
34 }a,b;
35
36 char s[M],tps[M];
37 int t,n,an,sqr=2000,bcnt;
38
39 void dfs(int r1,int r2)//将b中以r2为根结点的树合并到a中以r1为根结点的树中
40 {
41     F(i,0,1)if(~b.tr[r2][i])
42     {
43         if(a.tr[r1][i]==-1)a.nw(),a.tr[r1][i]=a.tot;
44         a.cnt[a.tr[r1][i]]|=b.cnt[b.tr[r2][i]];
45         dfs(a.tr[r1][i],b.tr[r2][i]);
46     }
47 }
48
49 void join(){dfs(0,0),b.init(),a.build();}//将b合并到a中
50
51 void decrypt()
52 {
53     int len=strlen(s);
54     int k=an%(len-1),ed=0;
55     F(i,1,len-1)tps[i]=s[i];
56     F(i,k+1,len-1)s[++ed]=tps[i];
57     F(i,1,k)s[++ed]=tps[i];
58 }
59
60 int main()
61 {
62     scanf("%d",&t);
63     F(ic,1,t)
64     {
65         printf("Case #%d:\n",ic);
66         scanf("%d",&n);
67         a.init(),b.init(),an=bcnt=0;
68         F(i,1,n)
69         {
70             scanf("%s",s),decrypt();
71             if(s[0]==‘+‘)
72             {
73                 b.insert(s+1),b.build(),bcnt++;
74                 if(bcnt>sqr)join();
75             }else printf("%d\n",(an=a.ask(s+1)+b.ask(s+1)));
76         }
77     }
78     return 0;
79 }

时间: 2024-10-27 10:55:41

hdu_4787_GRE Words Revenge(在线AC自动机)的相关文章

hdu 4787 GRE Words Revenge 在线AC自动机

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 Problem Description Now Coach Pang is preparing for the Graduate Record Examina

HDOJ 题目4787 GRE Words Revenge(在线ac自动机,离线也可做)

GRE Words Revenge Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 327680/327680 K (Java/Others) Total Submission(s): 1570    Accepted Submission(s): 352 Problem Description Now Coach Pang is preparing for the Graduate Record Examinations as

HDU3341 Lost&#39;s revenge(AC自动机+DP)

题目是给一个DNA重新排列使其包含最多的数论基因. 考虑到内存大概就只能这么表示状态: dp[i][A][C][G][T],表示包含各碱基个数为ACGT且当前后缀状态为自动机第i的结点的字符串最多的数论基因数 其中ACGT可以hash成一个整数(a*C*G*T+c*G*T+g*T+T),这样用二维数组就行了,而第二维最多也就11*11*11*11个. 接下来转移依然是我为人人型,我是丢进一个队列,用队列来更新状态的值. 这题果然挺卡常数的,只好手写队列,最后4500msAC,还是差点超时,代码也

【HDU3341】 Lost&#39;s revenge (AC自动机+状压DP)

Lost's revenge Time Limit: 5000MS Memory Limit: 65535KB 64bit IO Format: %I64d & %I64u Description Lost and AekdyCoin are friends. They always play "number game"(A boring game based on number theory) together. We all know that AekdyCoin is t

HDU 3341 Lost&#39;s revenge(AC自动机+状压DP)

Lost's revenge Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)Total Submission(s): 4548    Accepted Submission(s): 1274 Problem Description Lost and AekdyCoin are friends. They always play "number game"(A bor

CodeForces - 710F:String Set Queries (二进制分组 处理 在线AC自动机)

ou should process m queries over a set D of strings. Each query is one of three kinds: Add a string s to the set D. It is guaranteed that the string s was not added before. Delete a string s from the set D. It is guaranteed that the string s is in th

HDU4787 GRE Words Revenge(AC自动机 分块 合并)

题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=4787 Description Now Coach Pang is preparing for the Graduate Record Examinations as George did in 2011. At each day, Coach Pang can: "+w": learn a word w "?p": read a paragraph p, an

HDU 3341 Lost&#39;s revenge AC自动机+dp

Lost's revenge Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)Total Submission(s): 3757    Accepted Submission(s): 1020 Problem Description Lost and AekdyCoin are friends. They always play "number game"(A bor

Hdu 3341 Lost&#39;s revenge (ac自动机+dp+hash)

题目大意: 给出很多个DNA串,每一个串的价值为1,最后给出一个长串,要你重新排列最后的串使之它所有的子串的权值和最大. 思路分析: 最先容易想到的思路就是搜!管她3721..直接一个字符一个字符的码,然后在AC自动机上判断最后的权值.TLE哟. 然后发现搜过不去,那就dp咯.再容易想到的就是dp[i][a][b][c][d] 表示此时遍历AC自动机的节点在i,然后构成了a个A,b个G,c个C,d个T的权值. 再一看内存,500*40*40*40*40...然后...就没有然后了 再想,因为它说