• luogu3346 诸神眷顾的幻想乡 (广义SAM)


    首先,让每一个叶节点做一次树根的话,每个路径一定至少有一次会变成直上直下的

    于是对于每个叶节点作为根产生的20个trie树,把它们建到同一个广义SAM里

    建法是对每个trie dfs去建,last就是父亲的那个节点;每次做一个新trie时,last给成root

    然后答案就是每个节点表示的长度和

     1 #include<bits/stdc++.h>
     2 #define pa pair<int,int>
     3 #define CLR(a,x) memset(a,x,sizeof(a))
     4 #define MP make_pair
     5 using namespace std;
     6 typedef long long ll;
     7 const int maxn=1e5+10,maxp=4e6+10;
     8 
     9 inline char gc(){
    10     return getchar();
    11     static const int maxs=1<<16;static char buf[maxs],*p1=buf,*p2=buf;
    12     return p1==p2&&(p2=(p1=buf)+fread(buf,1,maxs,stdin),p1==p2)?EOF:*p1++;
    13 }
    14 inline ll rd(){
    15     ll x=0;char c=gc();bool neg=0;
    16     while(c<'0'||c>'9'){if(c=='-') neg=1;c=gc();}
    17     while(c>='0'&&c<='9') x=(x<<1)+(x<<3)+c-'0',c=gc();
    18     return neg?(~x+1):x;
    19 }
    20 
    21 int N,C,eg[maxn*2][2],egh[maxn],ect,dgr[maxn];
    22 int col[maxn];
    23 int tr[maxp][12],fa[maxp],len[maxp],pct=1,rt=1;
    24 
    25 inline void adeg(int a,int b){
    26     eg[++ect][0]=b,eg[ect][1]=egh[a],egh[a]=ect;
    27     dgr[a]++;
    28 }
    29 
    30 inline int insert(int x,int o){
    31     int p=++pct;
    32     len[p]=len[o]+1;
    33     for(;o&&!tr[o][x];o=fa[o]) tr[o][x]=p;
    34     if(!o){fa[p]=rt;return p;}
    35     int q=tr[o][x];
    36     if(len[q]==len[o]+1){fa[p]=q;return p;}
    37     int qq=++pct;
    38     memcpy(tr[qq],tr[q],sizeof(tr[qq]));
    39     len[qq]=len[o]+1;fa[qq]=fa[q],fa[q]=fa[p]=qq;
    40     for(;o&&tr[o][x]==q;o=fa[o]) tr[o][x]=qq;
    41     return p;
    42 }
    43 
    44 inline void dfs(int x,int f,int p){
    45     p=insert(col[x],p);
    46     for(int i=egh[x];i;i=eg[i][1]){
    47         int b=eg[i][0];if(b==f) continue;
    48         dfs(b,x,p);    
    49     }
    50 }
    51 
    52 int main(){
    53     //freopen("","r",stdin);
    54     int i,j,k;
    55     N=rd(),C=rd();
    56     for(i=1;i<=N;i++) col[i]=rd();
    57     for(i=1;i<N;i++){
    58         int a=rd(),b=rd();
    59         adeg(a,b);adeg(b,a);
    60     }
    61       for(i=1;i<=N;i++){
    62           if(dgr[i]==1) dfs(i,0,rt);
    63       }
    64       ll ans=0;
    65       for(i=2;i<=pct;i++) ans+=len[i]-len[fa[i]];
    66     printf("%lld
    ",ans);
    67     return 0;
    68 }
  • 相关阅读:
    JAVA BIO至NIO演进
    spring源码分析系列 (15) 设计模式解析
    java设计模式解析(1) Observer观察者模式
    spring源码分析系列 (8) FactoryBean工厂类机制
    spring如何解决单例循环依赖问题?
    spring源码分析系列
    java引用类型简述
    Redis简单延时队列
    MYSQL时间类别总结: TIMESTAMP、DATETIME、DATE、TIME、YEAR
    虚拟机安装centos7
  • 原文地址:https://www.cnblogs.com/Ressed/p/10205462.html
Copyright © 2020-2023  润新知