zoukankan      html  css  js  c++  java
  • bzoj3998: [TJOI2015]弦论

    前几天写的题,今天补写个blog

    T的情况get right集合的时候特判一下。

    因为SAM就是有序的,所以可以dfs求解。

    把parent树构建出来,sum表示当前子树的right和,搜一下就出来了。

    upd:第二次写这个题,搜索的时候记得减去right[now]

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    
    int len,a[1100000];
    struct node
    {
        int w[30];
    }ch[1100000];int root,last,cnt;
    int dep[1100000],parent[1100000];
    void add(int k)
    {
        int x=a[k];
        int now=++cnt,p=last;
        dep[now]=k;
        
        while(p!=0&&ch[p].w[x]==0)ch[p].w[x]=now,p=parent[p];
        if(p==0)parent[now]=root;
        else
        {
            int pre=ch[p].w[x];
            if(dep[p]+1==dep[pre])parent[now]=pre;
            else
            {
                int npre=++cnt;
                ch[npre]=ch[pre];
                dep[npre]=dep[p]+1;
                parent[npre]=parent[pre];
                
                parent[now]=parent[pre]=npre;
                while(ch[p].w[x]==pre)ch[p].w[x]=npre,p=parent[p];
            }
        }
        last=now;
    }
    int Rsort[1100000],sa[1100000];
    int Right[1100000];
    void get_Right(int T)
    {
        for(int i=1;i<=cnt;i++)Rsort[dep[i]]++;
        for(int i=1;i<=len;i++)Rsort[i]+=Rsort[i-1];
        for(int i=cnt;i>=1;i--)sa[Rsort[dep[i]]--]=i;
        
        int now=root;
        for(int i=1;i<=len;i++)
        {
            int x=a[i];
            now=ch[now].w[x];
            Right[now]++;
        }
        for(int i=cnt;i>=1;i--)
        {
            if(T==1)
                Right[parent[sa[i]]]+=Right[sa[i]];
            else
                Right[sa[i]]=1;
        }
        Right[root]=0;
    }
    
    int T,k;
    int sum[1100000];
    void dfs(int now)
    {
        if(k<=Right[now])return ;
        k-=Right[now];
        for(int x=1;x<=26;x++)
        {
            if(ch[now].w[x]!=0)
            {
                int next=ch[now].w[x];
                if(k>sum[next])k-=sum[next];
                else
                {
                    printf("%c",x+'a'-1);
                    dfs(next);
                    return ;
                }
            }
        }
    }
    
    char ss[1100000];
    int main()
    {
        scanf("%s",ss+1);len=strlen(ss+1);
        for(int i=1;i<=len;i++)a[i]=ss[i]-'a'+1;
        
        root=last=cnt=1;
        for(int i=1;i<=len;i++)add(i);
        
        scanf("%d%d",&T,&k);
        get_Right(T);
        
        for(int i=cnt;i>=1;i--)
        {
            int now=sa[i];sum[now]=Right[now];
            for(int x=1;x<=26;x++)
                if(ch[now].w[x]!=0)sum[now]+=sum[ch[now].w[x]];
        }
        if(k>sum[root])printf("-1
    ");
        else dfs(root);
        return 0;
    }
    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    
    int a[510000],len;
    struct SAM
    {
        int w[30],dep,fail;
    }ch[1100000];int last,cnt;
    void insert(int dep,int x)
    {
        int pre=last,now=++cnt; ch[now].dep=dep;
        last=now;
        
        while(pre!=0&&ch[pre].w[x]==0)
            ch[pre].w[x]=now, pre=ch[pre].fail;
        if(pre==0)ch[now].fail=1;
        else
        {
            int nxt=ch[pre].w[x];
            if(ch[nxt].dep==ch[pre].dep+1)ch[now].fail=nxt;
            else
            {
                int nnxt=++cnt;
                ch[nnxt]=ch[nxt];
                ch[nnxt].dep=ch[pre].dep+1;
                
                ch[nxt].fail=ch[now].fail=nnxt;
                while(pre!=0&&ch[pre].w[x]==nxt)
                    ch[pre].w[x]=nnxt, pre=ch[pre].fail;
            }
        }
    }
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~init~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    int T,Right[1100000];//根到当前节点组成的子串出现次数 
    int Rsort[1100000],sa[1100000];
    void GetRight()
    {
        memset(Rsort,0,sizeof(Rsort));
        for(int i=1;i<=cnt;i++)Rsort[ch[i].dep]++;
        for(int i=1;i<=len;i++)Rsort[i]+=Rsort[i-1];
        for(int i=cnt;i>=1;i--)sa[Rsort[ch[i].dep]--]=i;
        
        int now=1;
        memset(Right,0,sizeof(Right));
        for(int i=1;i<=len;i++) now=ch[now].w[a[i]], Right[now]++;
        for(int i=cnt;i>=1;i--)
        {
            int u=sa[i],v=ch[u].fail;
            if(T==0)Right[u]=1;
            else     Right[v]+=Right[u];
        }
        Right[1]=0;
    }
    int sum[1100000];//以根到当前节点为前缀的子串个数 
    void GetSum()
    {
        for(int i=cnt;i>=1;i--)
        {
            int now=sa[i];sum[now]=Right[now];
            for(int x=1;x<=26;x++)
                if(ch[now].w[x]!=0)sum[now]+=sum[ch[now].w[x]];
        }
    }
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    //------------------------------------------------------SAM-----------------------------------------------------------------
    
    int K;
    void dfs(int now)
    {
        if(K==Right[now])return ;
        K-=Right[now];
        for(int x=1;x<=26;x++)
            if(ch[now].w[x]!=0)
            {
                if(sum[ch[now].w[x]]>=K)
                {
                    printf("%c",x+'a'-1);
                    dfs(ch[now].w[x]);
                    return ;
                }
                else K-=sum[ch[now].w[x]];
            }
    }
    
    //-----------------------------------------------------solve----------------------------------------------------------------
    
    char ss[510000];
    int main()
    {
        scanf("%s%d%d",ss+1,&T,&K);
        last=cnt=1; len=strlen(ss+1);
        for(int i=1;i<=len;i++)
            a[i]=ss[i]-'a'+1, insert(i,a[i]);
        GetRight();
        GetSum();
        
        if(K>sum[1])printf("-1
    ");
        else dfs(1);    
        return 0;
    }
  • 相关阅读:
    Webdynpro Debug
    Smartforms SpoolId(转)
    BAPI_ACC_DOCUMENT_POST相关增强的实现
    angular factory service provider
    angularjs directive指令 link在渲染完成之后执行
    angularjs ui-router传值
    angularjs 常用 工具包
    angularJs-destroy事件
    angularjs 取消/中止 ajax请求
    angular-ui-router中的$stateProvider设置
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/8688264.html
Copyright © 2011-2022 走看看