zoukankan      html  css  js  c++  java
  • P3346 [ZJOI2015]诸神眷顾的幻想乡(广义后缀自动机)

    诸神眷顾的幻想乡

    给出一棵树

    叶子节点<=20

    询问树上一共可能有多少个不同颜色序列

    颜色值域<=10

    这题有一个结论

    从树的所有叶子节点为根开始搜,搜到的从根到节点的路径

    包含树上所有叶子的路径

    观察到叶子节点的数量<=20

    那么就可以以每个叶子节点为根搜索,把搜到的路径

    依次插入同一颗字典树内

    然后对这个字典树建GSAM

    最后套板子即可

     
    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=3e6+100;
    vector<int> g[maxn];
    int ch[maxn][12],tol,tot=1;
    int len[maxn],link[maxn],nxt[maxn][12];
    int ed[maxn];
    int a[maxn];
    int n,c;
    void dfs (int u,int f,int ff) {
    	//在树上搜,同时把当前字符插入字典树
    	if (!ch[ff][a[u]]) ch[ff][a[u]]=++tol;
    	for (int v:g[u]) {
    		if (v==f) continue;
    		dfs(v,u,ch[ff][a[u]]);
    	}
    }
    int sam_extend (int c,int lst) {
    	int cur=++tot;
    	len[cur]=len[lst]+1;
    	int p=lst;
    	while (p&&!nxt[p][c]) {
    		nxt[p][c]=cur;
    		p=link[p];
    	}
    	if (!p) {
    		link[cur]=1;
    	}
    	else {
    		int q=nxt[p][c];
    		if (len[p]+1==len[q]) {
    			link[cur]=q;
    		}
    		else {
    			int clone=++tot;
    			len[clone]=len[p]+1;
    			for (int i=0;i<12;i++) {
    				nxt[clone][i]=nxt[q][i];
    			}
    			link[clone]=link[q];
    			while (p&&nxt[p][c]==q) {
    				nxt[p][c]=clone;
    				p=link[p];
    			}
    			link[q]=link[cur]=clone;
    		}
    	}
    	return cur;
    }
    void GSA (int u,int f,char lc) {
    	if (u) {
    		ed[u]=sam_extend(lc,ed[f]);
    	} 
    	for (int i=0;i<12;i++) {
    		if (ch[u][i]) {
    			GSA(ch[u][i],u,i);
    		}
    	}
    }
    int main () {
    	scanf("%d%d",&n,&c);
    	for (int i=1;i<=n;i++) scanf("%d",a+i);
    	for (int i=1;i<n;i++) {
    		int x,y;
    		scanf("%d%d",&x,&y);
    		g[x].push_back(y);
    		g[y].push_back(x);
    	}
    	for (int i=1;i<=n;i++) {
    		if (g[i].size()>1) continue;
    		dfs(i,0,0);
    	}
    	ed[0]=1;
    	GSA(0,-1,0);
    	long long ans=0;
    	for (int i=2;i<=tot;i++) ans+=len[i]-len[link[i]];
    	printf("%lld
    ",ans);
    	
    }
  • 相关阅读:
    缺失的第一个正数
    tuple用法
    整数转罗马数字
    三种时间格式的转换
    不同包的调用
    正则表达式
    lgb模板
    线性回归
    时间序列的特征
    3D聚类
  • 原文地址:https://www.cnblogs.com/zhanglichen/p/15018129.html
Copyright © 2011-2022 走看看