HDU 4641 K-string Suffix Automata Union Search

http://acm.hdu.edu.cn/showproblem.php?pid=4641

https://blog.csdn.net/asdfgh0308/article/details/40969047

Given a lowercase letter string, 1 a means adding a lowercase letter a at the end of the string, and 2 means how many seed strings currently appear more than or equal to K.

It is enough to find the bucket sort of the number of occurrences (can it be said to be a topological sort?), and the type is t[i].len-t[t[i].f].len.

The online processing is a direct scan, and the time complexity is O(tree height*m).

The offline method is to complete all the addition operations first, and then remove the letters to find the number of substrings in reverse. You can use the union search to reduce the time complexity (only the substring represented by the total father in each connected block contributes to the current answer) , which guarantees the average number of scans per point).

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cmath>
 6 #include<queue>
 7 using namespace std;
 8 #define LL long long
 9 const int maxn=60100;
10 int n,m,K;
11 char ch[maxn*10],ch1[3];
12 int e[maxn*4]={},b[maxn*5]={},siz;
13 struct nod{
14     int sig[26],f,len;
15 }t[maxn*10]; int tot,la;
16 
17 int cnt[maxn*10]={},rk[maxn*10]={};
18 int fa[maxn*10]={},sub[maxn*10]={},g[maxn*10]={};
19 LL ans[maxn*4]={};
20 
21 void addit(int z){
22     int x=++tot,i=la; t[x].len=t[i].len+1;
23     b[siz]=x;
24     for(;i&&!t[i].sig[z];i=t[i].f)t[i].sig[z]=x;
25     if(!i)t[x].f=1;
26     else{
27         int y=t[i].sig[z];
28         if(t[y].len==t[i].len+1)t[x].f=y;
29         else{
30             int p=++tot;
31             t[p]=t[y];t[p].len=t[i].len+1;
32             t[y].f=t[x].f=p;
33             for(;i&&t[i].sig[z]==y;i=t[i].f)t[i].sig[z]=p;
34         }
35     }
36     la=x;
37 }
38 void msort(){
39     int i;
40     for(i=0;i<=siz;i++)cnt[i]=0;
41     for(i=2;i<=tot;i++)cnt[t[i].len]++;
42     for(i=1;i<=siz;i++)cnt[i]+=cnt[i-1];
43     for(i=tot;i>1;i--)rk[cnt[t[i].len]--]=i;
44 }
45 int getfa(int x){
46     int y=x,z;
47     while(y!=fa[y])y=fa[y];
48     while(x!=fa[x]){ z=x; x=fa[x];fa[z]=y;}
49     return fa[x];
50 }
51 int main(){
52     int i,p,y; LL num;
53     while(~scanf("%d%d%d",&n,&m,&K)){
54         memset(t,0,sizeof(t)); tot=1; la=1; siz=0;
55         scanf("%s",ch);
56         for(i=0;i<n;++i){ addit(ch[i]-'a'); ++siz; }
57         for(i=1;i<=m;i++){
58             scanf("%d",&e[i]); 
59             if(e[i]==1){ scanf("%s",ch1); addit(ch1[0]-'a'); ch[siz++]=ch1[0]; }
60         }
61         msort(); p=1,num=0;
62         for(i=1;i<=tot;i++){ g[i]=0; fa[i]=i; sub[i]=0;}
63         for(i=0;i<siz;++i){ p=t[p].sig[ch[i]-'a']; ++g[p]; }
64         for(i=tot-1;i>0;i--){ p=rk[i]; if(t[p].f!=1)g[t[p].f]+=g[p]; }
65         for(i=2;i<=tot;++i){ if(g[i]>=K) num+=t[i].len-t[t[i].f].len; }
66         for(i=m;i>0;i--){
 67              if (e[i]== 2 )ans[i]= num;
68              else {
 69                  p=b[-- siz];
70                  y= getfa(p);
71                  while (y!= 1 &&g[y]<K){ fa[y]=getfa(t[y].f); y= fa[y];}
 72                  y= getfa(p);
73                  if (y== 1 ) continue ;
74                  sub[y]++ ;
75                  while (y!= 1 &&(g[y]-sub[y]< K)){
 76                      num-=t[y].len-t[t[y].f].len;
77                     p=getfa(t[y].f);
78                     sub[p]+=sub[y]; fa[y]=p;
79                     y=fa[y];
80                 }
81             }
82         }
83         for(i=1;i<=m;++i)if(e[i]==2)printf("%lld\n",ans[i]);
84     }
85     return 0;
86 }
View Code

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325082987&siteId=291194637