bzoj3926 / luoguP3346 [Zjoi2015] gods favored fantasy the township (generalized suffix automaton constructed on Trie)

bzoj Luogu

Problem solution time

Give you a tree without roots trie (trie you call this tree?), I have to ask you to select a different path How many strings can be formed.

Sunflower field structure is rather special, just adjacent to the amount of space a space no more than 20. -> only no more than 20 leaves.

Just look at you read the question, if you misread the meaning of this sentence you to white.

How to ensure the integrity of this tree to enumerate all possible string it?

We build a certain point as the root generalized SAM, it is clear that each point to the root Fangxiang Yan strings are only on display is not credited in the SAM.

For a leaf node, it is only to build root SAM, use it as a starting point to extend the string will be recorded.

For a non-leaf nodes, it is clear that there must be two different directions in its leaf nodes.

We only need to build broad SAM root for each leaf node on the statistics can be together.

The number of different strings in nature $ \ Sigma len [x] -len [pre [x]] $.

#include<bits/stdc++.h>
using namespace std;
typedef long long lint;
namespace RKK
{
const int N=200011,L=30;
struct yuuka{int to,ne;}e[N];int he[N],ecnt,ind[N];
void addline(int f,int t)
{
    e[++ecnt].to=t;
    e[ecnt].ne=he[f];
    he[f]=ecnt;
    ind[t]++;
}
int n,str[N];
lint ans;
struct remilia{int tranc[10],len,pre;};
struct sakuya
{
    remilia s[N*20];
    int fin,size;
    sakuya(){fin=size=1;}
    void ins(int ch)
    {
        int npx,npy,lpx,lpy;
        if(s[fin].tranc[ch])
        {
            lpy=s[fin].tranc[ch],lpx=fin;
            if(s[lpy].len==s[lpx].len+1) fin=lpy;
            else
            {
                npy=++size;
                s[npy]=s[lpy];
                s[npy].len=s[lpx].len+1;
                s[lpy].pre=npy;
                while(s[lpx].tranc[ch]==lpy)
                {
                    s[lpx].tranc[ch]=npy;
                    lpx=s[lpx].pre;
                }
                fin=npy;
            }
            return;
        }
        npx=++size;
        s[npx].len=s[fin].len+1;
        for(lpx=fin;lpx&&!s[lpx].tranc[ch];lpx=s[lpx].pre) s[lpx].tranc[ch]=npx;
        if(!lpx) s[npx].pre=1;
        else
        {
            lpy=s[lpx].tranc[ch];
            if(s[lpy].len==s[lpx].len+1) s[npx].pre=lpy;
            else
            {
                npy=++size;
                s[npy]=s[lpy];
                s[npy].len=s[lpx].len+1;
                s[npx].pre=s[lpy].pre=npy;
                while(s[lpx].tranc[ch]==lpy)
                {
                    s[lpx].tranc[ch]=npy;
                    lpx=s[lpx].pre;
                }
            }
        }
        fin=npx;
    }
    void work(){for(int i=2;i<=size;i++) ans+=s[i].len-s[s[i].pre].len;}
}sam;
void dfs(int x,int f,int fi)
{
    sam.fin=fi,sam.ins(str[x]);
    int fl=sam.fin;
    for(int i=he[x],t=e[i].to;i;i=e[i].ne,t=e[i].to)if(t!=f)
        dfs(t,x,fl);
}
int Iris()
{
    scanf("%d%*d",&n);
    for(int i=1;i<=n;i++) scanf("%d",&str[i]);
    for(int i=1,x,y;i<n;i++) scanf("%d%d",&x,&y),addline(x,y),addline(y,x);
    for(int i=1;i<=n;i++)if(ind[i]==1) dfs(i,0,1);
    sam.work();
    printf("%lld\n",ans);
    return 0;
}
}
int main(){return RKK::Iris();}

Guess you like

Origin www.cnblogs.com/rikurika/p/12079124.html