1. 程式人生 > >CC TSUBSTR:Substrings on a Tree——題解

CC TSUBSTR:Substrings on a Tree——題解

LG putc ati pac main eof log html truct

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=++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; } } size[np]=1; 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; } size[1]=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/+

+++++++++++++++++++++++++++++++++++++++++++

CC TSUBSTR:Substrings on a Tree——題解