CC TSUBSTR:Substrings on a Tree——题解
https://www.codechef.com/problems/TSUBSTR
https://vjudge.net/problem/CodeChef-TSUBSTR
给一棵点权为字母的树,你只能从任意节点往下走得到一个字符串,求出可得到的不重复字符串数量和其中字典序第k小的字符串(在重新定义字母的字典序前提下)?
垃圾谷歌翻译坑我不浅。
广义后缀自动机处理之后就是BZOJ3998:[TJOI2015]弦论t=0的解法了。
注意空字符串也算。
#include<cstdio> #include<iostream> #include<queue> #include<cstring> #include<algorithm> #include<cctype> using namespace std; typedef long long ll; const int N=2e6+5; struct tree{ int a[26],fa,l; }tr[N]; struct node{ int to,nxt; }e[N]; char s[N]; int tot,cnt,head[N],pos[N]; ll a[N],w[N],size[N],sum[N]; bool vis[N]; queue<int>q; inline void add(int u,int v){ e[++cnt].to=v;e[cnt].nxt=head[u];head[u]=cnt; } inline int insert(int p,int c){ int np=tr[p].a[c]; if(np&&tr[np].l==tr[p].l+1)return np; np=++tot;tr[np].l=tr[p].l+1; for(;p&&!tr[p].a[c];p=tr[p].fa)tr[p].a[c]=np; if(!p)tr[np].fa=1; else{ int q=tr[p].a[c]; if(tr[p].l+1==tr[q].l)tr[np].fa=q; else{ int nq=++tot;tr[nq].l=tr[p].l+1; memcpy(tr[nq].a,tr[q].a,sizeof(tr[q].a)); tr[nq].fa=tr[q].fa;tr[q].fa=tr[np].fa=nq; for(;p&&tr[p].a[c]==q;p=tr[p].fa)tr[p].a[c]=nq; } } return np; } void bfs(int st){ tot=1; q.push(st);vis[st]=1; pos[st]=insert(1,s[st]-'a'); while(!q.empty()){ int u=q.front();q.pop(); for(int i=head[u];i;i=e[i].nxt){ int v=e[i].to; if(vis[v])continue; q.push(v);vis[v]=1; pos[v]=insert(pos[u],s[v]-'a'); } } } int main(){ int len,q; scanf("%d%d",&len,&q); scanf("%s",s+1); for(int i=1;i<len;i++){ int u,v; scanf("%d%d",&u,&v); add(u,v);add(v,u); } bfs(1); for(int i=1;i<=tot;i++)w[tr[i].l]++; for(int i=1;i<=len;i++)w[i]+=w[i-1]; for(int i=1;i<=tot;i++)a[w[tr[i].l]--]=i; for(int i=tot;i>=1;i--){ size[a[i]]=1; } for(int i=tot;i>=1;i--){ sum[a[i]]=size[a[i]]; for(int j=0;j<26;j++) if(tr[a[i]].a[j])sum[a[i]]+=sum[tr[a[i]].a[j]]; } printf("%lld\n",sum[1]); for(int i=1;i<=q;i++){ ll k; scanf("%s%lld",s,&k); if(k>sum[1]){puts("-1");continue;} int now=1; while(k>size[now]){ k-=size[now]; for(int j=0;j<26;j++){ if(k>sum[tr[now].a[s[j]-'a']]){ k-=sum[tr[now].a[s[j]-'a']]; }else{ now=tr[now].a[s[j]-'a']; putchar(s[j]); break; } } } puts(""); } return 0; }
+++++++++++++++++++++++++++++++++++++++++++
+本文作者:luyouqi233。 +
+欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+
+++++++++++++++++++++++++++++++++++++++++++