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

bzoj3998 [TJOI2015]弦论

时间:2018-01-28 16:32:05      阅读:178      评论:0      收藏:0      [点我收藏+]

标签:sum   gpo   col   前缀   字符串   ret   math   algorithm   str   

后缀自动机

我们建出后缀自动机,对于每个节点我们算出他和他的后继结点一共可以形成多少个不同的串,不同根据t来定义

这里我们不需要考虑每个节点代表的那些等价类字符串,因为那些字符串不同的前缀在到达这个节点前已经确定了,所以我们只需要在t=1时一下考虑right集合的大小,right集合的大小需要在parent树上pushup,乱搞一下就好了。

最后dfs一下即可。

发现bzoj榜上的时间都很接近,于是就在Troywar的帮助下卡了波常,然而只到了第一页,并没有快多少。

技术分享图片
 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <algorithm>
 5 #include <cmath>
 6 #define N 1000500
 7 using namespace std;
 8 int n,m,o;
 9 char s[N>>1];
10 int last,tot,mx[N],par[N],ch[N][26];
11 int val[N],sum[N],buc[N],q[N];
12 void add(int c){
13     int p=last,np=++tot;
14     mx[np]=mx[p]+1;val[np]=1;
15     for(;p&&!ch[p][c];p=par[p])ch[p][c]=np;
16     if(!p)  par[np]=1;
17     else{
18         int q=ch[p][c];
19         if(mx[q]==mx[p]+1)par[np]=q;
20         else{
21             int nq=++tot;
22             mx[nq]=mx[p]+1;
23             par[nq]=par[q];
24             memcpy(ch[nq],ch[q],sizeof ch[nq]);
25             par[q]=par[np]=nq;
26             for(;p&&ch[p][c]==q;p=par[p])ch[p][c]=nq;
27         }
28     }last=np;
29 }
30 void init(){
31     for(int i=1;i<=tot;i++)buc[mx[i]]++;
32     for(int i=1;i<=n;i++)buc[i]+=buc[i-1];
33     for(int i=tot;i;i--)q[buc[mx[i]]--]=i;
34     for(int i=tot;i;i--){
35         if(!o)val[q[i]]=1;
36         else val[par[q[i]]]+=val[q[i]];
37     }val[1]=0;
38     for(int i=tot;i;i--){
39         sum[q[i]]=val[q[i]];
40         for(int j=0;j<26;j++)
41             sum[q[i]]+=sum[ch[q[i]][j]];
42     }
43 }
44 void dfs(int x,int k){
45     if(k<=val[x])return ;
46     k-=val[x];
47     for(int i=0;i<26;i++)if(ch[x][i]){
48         if(sum[ch[x][i]]>=k){
49             putchar(i+a);
50             dfs(ch[x][i],k);
51             return ;
52         }k-=sum[ch[x][i]];
53     }
54 }
55 int main(){
56     last=++tot;
57     scanf("%s",s+1);
58     n=strlen(s+1);
59     for(int i=1;i<=n;i++)add(s[i]-a);
60     scanf("%d%d",&o,&m);
61     init();
62     if(m>sum[1])puts("-1");
63     else dfs(1,m);
64 }
View Code

 

bzoj3998 [TJOI2015]弦论

标签:sum   gpo   col   前缀   字符串   ret   math   algorithm   str   

原文地址:https://www.cnblogs.com/Ren-Ivan/p/8371261.html

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