zoukankan      html  css  js  c++  java
  • bzoj3926: [Zjoi2015]诸神眷顾的幻想乡

    因为叶子只有20个,那么对于每个叶子节点当作根建一棵trie,然后一条路径是某一个trie上的一条上到下的路径

    然后......广义sam sb题

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    typedef long long LL;
    
    struct node
    {
        int x,y,next;
    }a[210000];int len,last[110000];
    void ins(int x,int y)
    {
        len++;
        a[len].x=x;a[len].y=y;
        a[len].next=last[x];last[x]=len;
    }
    int lf[30];
    void findleaf(int x,int fr)
    {
        int t=0;
        for(int k=last[x];k;k=a[k].next)
        {
            int y=a[k].y;
            if(y!=fr)
            {
                t++;
                findleaf(y,x);
            }
        }
        if(t==0|(x==1&&t==1))lf[++lf[0]]=x;
    }
    
    //---------------------------------init:findleaf-----------------------------------------------------
    
    int col[110000];
    struct Trie
    {
        int w[15],col;
        void init(int COL){memset(w,0,sizeof(w));col=COL;}
    }tr[2100000];int trlen;
    int Trie_insert(int x,int now)
    {
        if(tr[now].w[x]==0)
            tr[now].w[x]=++trlen, tr[trlen].init(x);
        return tr[now].w[x];
    }
    
    int fr[2100000],pos[2100000];
    int head,tail,list[2100000];
    void Trie_merge(int rt)
    {
        fr[rt]=0,pos[0]=0;
        head=1,tail=2;list[1]=rt;
        while(head!=tail)
        {
            int x=list[head]; pos[x]=Trie_insert(col[x],pos[fr[x]]);
            for(int k=last[x];k;k=a[k].next)
            {
                int y=a[k].y;
                if(y!=fr[x])
                {
                    fr[y]=x;
                    list[tail++]=y;
                }
            }
            fr[x]=0;
            head++;
        }
    }
    void Trie_main()
    {
        trlen=0;
        for(int i=1;i<=lf[0];i++)Trie_merge(lf[i]);
    }
    
    //---------------------------------------maketrie---------------------------------------------------
    
    struct SAM
    {
        int w[15],dep,fail;
    }ch[4100000];int cnt;
    int SAM_insert(int pre,int x)
    {
        int now=++cnt;
        ch[now].dep=ch[pre].dep+1;
        
        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;
            }
        }
        return now;
    }
    
    int C;
    void SAM_main()
    {
        cnt=1;
        head=1,tail=1;
        pos[0]=1;
        for(int x=1;x<=C;x++)
            if(tr[0].w[x]!=0) fr[tr[0].w[x]]=0, list[tail++]=tr[0].w[x];
        while(head!=tail)
        {
            int now=list[head]; pos[now]=SAM_insert(pos[fr[now]],tr[now].col);
            for(int x=1;x<=C;x++)
                if(tr[now].w[x]!=0)
                {
                    fr[tr[now].w[x]]=now;
                    list[tail++]=tr[now].w[x];
                }
            head++;
        }
    }
    
    //---------------------------------------makeSAM----------------------------------------------------
    
    int main()
    {
        freopen("a.in","r",stdin);
        freopen("a.out","w",stdout);
        int n,x,y;
        scanf("%d%d",&n,&C);
        len=0;memset(last,0,sizeof(last));
        for(int i=1;i<=n;i++)scanf("%d",&col[i]),col[i]++;
        for(int i=1;i<n;i++)
        {
            scanf("%d%d",&x,&y);
            ins(x,y),ins(y,x);
        }
        findleaf(1,0);
        
        Trie_main();
        SAM_main();
        
        LL ans=0;
        for(int i=2;i<=cnt;i++)
            ans+=ch[i].dep-ch[ch[i].fail].dep;
        printf("%lld
    ",ans);
        
        return 0;
    }
  • 相关阅读:
    Map总结(HashMap, Hashtable, TreeMap, WeakHashMap等使用场景)
    IP地址资源的分配和管理
    破解中常见的指令及修改
    8086 CPU 寻址方式
    汇编指令速查
    关于ida pro的插件keypatch
    动态方式破解apk进阶篇(IDA调试so源码)
    IDA7.0安装keypatch和findcrypt-yara插件
    Android逆向之旅---动态方式破解apk进阶篇(IDA调试so源码)
    IDA动态调试技术及Dump内存
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/10058034.html
Copyright © 2011-2022 走看看