码迷,mamicode.com
首页 > 其他好文 > 详细

hdu 5343 MZL's Circle Zhou(后缀自动机)

时间:2017-09-25 20:48:46      阅读:161      评论:0      收藏:0      [点我收藏+]

标签:统计   题意   acm   ++   组成   hdu   can   char   style   

题目链接:hdu 5343 MZL‘s Circle Zhou

题意:

给你两个串A,B,问从A,B中选子串x,y,问x+y可以组成多少个不同的串,x和y可以为空。

题解:

贴一个官方的题解

技术分享

 

技术分享
 1 #include<bits/stdc++.h>
 2 #define mst(a,b) memset(a,b,sizeof(a))
 3 #define F(i,a,b) for(int i=(a);i<=(b);++i)
 4 using namespace std;
 5 using ll=unsigned long long;
 6 
 7 const int N=1e5+7,tyn=26,M=N*2;
 8 struct SAM{
 9     int tr[M][tyn],f[M],ml[M],ed,last,p,x,r,q;
10     int b[M],d[M]; ll cnt[M];
11     inline int gid(char x){return x-a;}
12     inline void nc(int s,int &p){
13         ml[p=++ed]=s,f[ed]=cnt[ed]=0,mst(tr[ed],0);
14     }
15     void clear(){ed=0,nc(0,last);}
16     void add(int w){
17         nc(ml[x=last]+1,p),last=p,cnt[p]=1;
18         while(x&&!tr[x][w])tr[x][w]=p,x=f[x];
19         if(!x)f[p]=1;
20         else if(ml[x]+1==ml[q=tr[x][w]])f[p]=q;
21         else{
22             nc(ml[x]+1,r),f[r]=f[q],f[p]=f[q]=r;
23             memcpy(tr[r],tr[q],sizeof(tr[r]));
24             while(x&&tr[x][w]==q)tr[x][w]=r,x=f[x];
25         }
26     }
27     void upright(int mx=0){
28         F(i,0,ed)d[i]=0;
29         F(i,1,ed)d[mx<ml[i]?mx=ml[i]:ml[i]]++;
30         F(i,1,mx)d[i]+=d[i-1];
31         F(i,1,ed)b[d[ml[i]]--]=i;
32     }
33     void build(char *s){for(int i=1;s[i];i++)add(gid(s[i]));}
34 }sam[2];
35 
36 
37 char s[N];
38 int t;
39 
40 void work()
41 {
42     for(int i=sam[1].ed;i;--i)
43     {
44         int x=sam[1].b[i];
45         sam[1].cnt[x]=1;
46         F(j,0,25)
47         {
48             int v=sam[1].tr[x][j];
49             if(v)sam[1].cnt[x]+=sam[1].cnt[v];
50         }
51     }
52 }
53 
54 void solve()
55 {
56     for(int i=sam[0].ed;i;--i)
57     {
58         int x=sam[0].b[i];
59         sam[0].cnt[x]=0;
60         F(j,0,25)
61         {
62             int v=sam[0].tr[x][j];
63             if(v)sam[0].cnt[x]+=sam[0].cnt[v];
64             else sam[0].cnt[x]+=sam[1].cnt[sam[1].tr[1][j]];
65         }
66     }
67     ll ans=sam[0].cnt[1];//x为空的时候已经统计过了
68     F(i,2,sam[0].ed)ans+=sam[0].ml[i]-sam[0].ml[sam[0].f[i]];//y为空的时候
69     printf("%llu\n",ans+1);//+1表示x和y都为空的时候
70 }
71 
72 int main(){
73     scanf("%d",&t);
74     while(t--)
75     {
76         scanf("%s",s+1);
77         sam[0].clear(),sam[0].build(s),sam[0].upright();
78         scanf("%s",s+1);
79         sam[1].clear(),sam[1].build(s),sam[1].upright();
80         work();solve();
81     }
82     return 0;
83 }
View Code

 

hdu 5343 MZL's Circle Zhou(后缀自动机)

标签:统计   题意   acm   ++   组成   hdu   can   char   style   

原文地址:http://www.cnblogs.com/bin-gege/p/7593701.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!