zoukankan      html  css  js  c++  java
  • bzoj3926: [Zjoi2015]诸神眷顾的幻想乡 后缀自动机在tire树上拓展

    题意:有棵树每个点有个颜色(不超过10种),每个节点不超过20个儿子,问你每两点之间的颜色序列不同的有多少种
    题解:先建出树,对于每个叶子节点,bfs一遍建在sam上,每次保留当前点在sam上的位置,拓展时用父亲节点在sam上的位置当成last即可.然后统计sam本质不同的字符串有多少个
    注:dfs建树复杂度是错的,但是也能过这题

    /**************************************************************
        Problem: 3926
        User: walfy
        Language: C++
        Result: Accepted
        Time:3612 ms
        Memory:270836 kb
    ****************************************************************/
     
    //#pragma GCC optimize(2)
    //#pragma GCC optimize(3)
    //#pragma GCC optimize(4)
    //#pragma GCC optimize("unroll-loops")
    //#pragma comment(linker, "/stack:200000000")
    //#pragma GCC optimize("Ofast,no-stack-protector")
    //#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define db double
    #define mp make_pair
    #define pb push_back
    #define pi acos(-1.0)
    #define ll long long
    #define vi vector<int>
    #define mod 1000000007
    #define ld long double
    //#define C 0.5772156649
    //#define ls l,m,rt<<1
    //#define rs m+1,r,rt<<1|1
    #define pll pair<ll,ll>
    #define pil pair<int,ll>
    #define pli pair<ll,int>
    #define pii pair<int,int>
    #define ull unsigned long long
    //#define base 1000000000000000000
    #define fin freopen("a.txt","r",stdin)
    #define fout freopen("a.txt","w",stdout)
    #define fio ios::sync_with_stdio(false);cin.tie(0)
    inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
    inline void sub(ll &a,ll b){a-=b;if(a<0)a+=mod;}
    inline void add(ll &a,ll b){a+=b;if(a>=mod)a-=mod;}
    template<typename T>inline T const& MAX(T const &a,T const &b){return a>b?a:b;}
    template<typename T>inline T const& MIN(T const &a,T const &b){return a<b?a:b;}
    inline ll qp(ll a,ll b){ll ans=1;while(b){if(b&1)ans=ans*a%mod;a=a*a%mod,b>>=1;}return ans;}
    inline ll qp(ll a,ll b,ll c){ll ans=1;while(b){if(b&1)ans=ans*a%c;a=a*a%c,b>>=1;}return ans;}
     
    using namespace std;
     
    const ull ba=233;
    const db eps=1e-5;
    const ll INF=0x3f3f3f3f3f3f3f3f;
    const int N=100000+10,maxn=1000000+10,inf=0x3f3f3f3f;
     
    struct SAM{
        int last,cnt;
        int ch[N*40][15],fa[N*40],l[N*40];
        int ins(int y,int x)
        {
            last=y;
            int p=last,np=++cnt;last=np;l[np]=l[p]+1;
            for(;p&&!ch[p][x];p=fa[p])ch[p][x]=np;
            if(!p)fa[np]=1;
            else
            {
                int q=ch[p][x];
                if(l[q]==l[p]+1)fa[np]=q;
                else
                {
                    int nq=++cnt;l[nq]=l[p]+1;
                    memcpy(ch[nq],ch[q],sizeof ch[q]);
                    fa[nq]=fa[q];fa[q]=fa[np]=nq;
                    for(;ch[p][x]==q;p=fa[p])ch[p][x]=nq;
                }
            }
            return last;
        }
        void build()
        {
            cnt=last=1;
        }
        ll cal()
        {
            ll ans=0;
            for(int i=1;i<=cnt;i++)ans+=l[i]-l[fa[i]];
            return ans;
        }
    }sam;
    int a[N],d[N];
    bool vis[N];
    struct Tire{
        vector<int>v[N];
        int id[N];
        void ins(int a,int b){v[a].pb(b);v[b].pb(a);}
        void bfs(int u)
        {
            memset(vis,0,sizeof vis);
            queue<int>q;q.push(u);vis[u]=1;
            id[u]=sam.ins(1,a[u]);
            while(!q.empty())
            {
                u=q.front();q.pop();
                for(int i=0;i<v[u].size();i++)if(!vis[v[u][i]])
                {
                    int x=v[u][i];
                    vis[x]=1;q.push(x);
                    id[x]=sam.ins(id[u],a[x]);
                }
            }
        }
    }t;
    int main()
    {
        int n,c;scanf("%d%d",&n,&c);
        for(int i=1;i<=n;i++)scanf("%d",&a[i]);
        for(int i=1;i<n;i++)
        {
            int a,b;scanf("%d%d",&a,&b);
            t.ins(a,b);d[a]++,d[b]++;
        }
        sam.build();
        for(int i=1;i<=n;i++)if(d[i]==1)t.bfs(i);
        printf("%lld
    ",sam.cal());
        return 0;
    }
    /********************
     
    ********************/
    
  • 相关阅读:
    Java如何编写自动售票机程序
    install windows service
    redis SERVER INSTALL WINDOWS SERVICE
    上传文件
    This problem will occur when running in 64 bit mode with the 32 bit Oracle client components installed.
    解决Uploadify上传控件加载导致的GET 404 Not Found问题
    OracleServiceORCL服务不见了怎么办
    Access to the temp directory is denied. Identity 'NT AUTHORITYNETWORK SERVICE' under which XmlSerializer is running does not have sufficient permiss
    MSSQL Server 2008 数据库安装失败
    数据库数据导出成XML文件
  • 原文地址:https://www.cnblogs.com/acjiumeng/p/10661531.html
Copyright © 2011-2022 走看看