其他分享
首页 > 其他分享> > P3975 [TJOI2015]弦论

P3975 [TJOI2015]弦论

作者:互联网

题意

第一问有一个经典做法:学习笔记

对于第二问,其实就是对于一个状态的所有串,第一问看成一个,第二问看成多个。

code:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=5*1e5+10;
int n,type,m,tot,last,cnt;
int head[maxn<<1],in[maxn<<1],size[maxn<<1];
ll f[maxn<<1];
char s[maxn];
struct edge{int to,nxt;}e[maxn<<2];
struct Sam
{
    int fa,len;
    int ch[26];
}sam[maxn<<1];
inline void add(int u,int v)
{
    e[++cnt].nxt=head[u];
    head[u]=cnt;
    e[cnt].to=v;
    in[v]++;
}
inline void sam_init(){sam[0].fa=-1,sam[0].len=0;last=0;}
inline void sam_add(int c)
{
    int now=++tot;sam[now].len=sam[last].len+1;size[now]=1;
    int p=last;
    while(~p&&!sam[p].ch[c])sam[p].ch[c]=now,p=sam[p].fa;
    if(p==-1){sam[now].fa=0;last=now;return;}
    int q=sam[p].ch[c];
    if(sam[q].len==sam[p].len+1)sam[now].fa=q;
    else
    {
        int nowq=++tot;
        sam[nowq].len=sam[p].len+1;
        memcpy(sam[nowq].ch,sam[q].ch,sizeof(sam[q].ch));
        sam[nowq].fa=sam[q].fa;sam[q].fa=sam[now].fa=nowq;
        while(~p&&sam[p].ch[c]==q)sam[p].ch[c]=nowq,p=sam[p].fa;
    }
    last=now;
}
void dfs(int x)
{
    for(int i=head[x];i;i=e[i].nxt)
        dfs(e[i].to),size[x]+=size[e[i].to];
}
inline void work(int op)
{
    if(op)
    {
        for(int i=1;i<=tot;i++)add(sam[i].fa,i);
        dfs(0);
    }
    memset(head,0,sizeof(head));
    memset(in,0,sizeof(in));
    cnt=0;
    for(int i=0;i<=tot;i++)
        for(int j=0;j<26;j++)
            if(sam[i].ch[j])add(sam[i].ch[j],i);
    queue<int>q;
    for(int i=0;i<=tot;i++)if(!in[i])q.push(i);
    while(!q.empty())
    {
        int x=q.front();q.pop();
        f[x]=!op?1:size[x];
        //cerr<<f[x]<<endl;
        for(int i=0;i<26;i++)if(sam[x].ch[i])f[x]+=f[sam[x].ch[i]];
        for(int i=head[x];i;i=e[i].nxt)
        {
            int y=e[i].to;
            if(!(--in[y]))q.push(y);
        }
    }
    f[0]--;
    //cerr<<f[0]<<endl;
}
int main()
{
    scanf("%s%d%d",s+1,&type,&m);n=strlen(s+1);
    sam_init();
    for(int i=1;i<=n;i++)sam_add(s[i]-'a');
    work(type);
    if(m>f[0]){puts("-1");return 0;}
    int now=0;
    while(m)
    {
        for(int i=0;i<26;i++)
        {
            if(!sam[now].ch[i])continue;
            if(f[sam[now].ch[i]]<m)m-=f[sam[now].ch[i]];
            else 
            {
                m-=!type?1:size[sam[now].ch[i]];now=sam[now].ch[i];
                putchar(i+'a');break;
            }
        }
    }
    return 0;
} 

标签:code,P3975,int,弦论,long,看成,TJOI2015,题意
来源: https://www.cnblogs.com/nofind/p/12047551.html