zoukankan      html  css  js  c++  java
  • 【[ZJOI2015]诸神眷顾的幻想乡】

    题目

    听说这是广义(SAM)的板子

    看来对于广义(SAM)我也就只会板子了

    叶子数很少,所以可以枚举每一个叶子节点作为根建一遍(Trie)

    只需要对(Trie)树建出(SAM)就好了

    跟对单串建(SAM)不同的就是(last)节点是这个点在(Trie)树上的父亲

    并不是很清楚为什么需要在(son[f][c]!=0)的时候特判一下

    就这样吧

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #define maxn 100005
    #define M 4000005
    #define re register
    #define LL long long
    #define max(a,b) ((a)>(b)?(a):(b))
    #define min(a,b) ((a)<(b)?(a):(b))
    inline int read()
    {
    	char c=getchar();int x=0;while(c<'0'||c>'9') c=getchar();
    	while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();
    	return x;
    }
    struct E{int v,nxt;} e[maxn<<1];
    int c[maxn],head[maxn],lst=1,cnt=1,d[maxn],num,n,m;
    int len[M],fa[M],son[M][10];
    inline void add(int x,int y) {e[++num].v=y;e[num].nxt=head[x];head[x]=num;}
    inline int ins(int f,int c)
    {
    	if(son[f][c])
    	{
    		int x=son[f][c];
    		if(len[f]+1==len[x]) {return x;}
    		int y=++cnt;
    		len[y]=len[f]+1,fa[y]=fa[x],fa[x]=y;
    		for(re int i=0;i<m;i++) son[y][i]=son[x][i];
    		while(f&&son[f][c]==x) son[f][c]=y,f=fa[f];
    		return y;
    	}
    	int p=++cnt; lst=p;
    	len[p]=len[f]+1;
    	while(f&&!son[f][c]) son[f][c]=p,f=fa[f];
    	if(!f) {fa[p]=1;return lst;}
    	int x=son[f][c];
    	if(len[f]+1==len[x]) {fa[p]=x;return lst;}
    	int y=++cnt;
    	len[y]=len[f]+1,fa[y]=fa[x],fa[x]=fa[p]=y;
    	for(re int i=0;i<m;i++) son[y][i]=son[x][i];
    	while(f&&son[f][c]==x) son[f][c]=y,f=fa[f];
    	return lst;
    }
    void dfs(int x,int f,int p)
    {
    	int t=ins(p,c[x]);
    	for(re int i=head[x];i;i=e[i].nxt) 
    	if(e[i].v!=f) dfs(e[i].v,x,t);
    }
    int main()
    {
    	n=read(),m=read();int x,y;LL ans=0;
    	for(re int i=1;i<=n;i++) c[i]=read();
    	for(re int i=1;i<n;i++) x=read(),y=read(),add(x,y),add(y,x),d[x]++,d[y]++;
    	for(re int i=1;i<=n;i++) if(d[i]==1) dfs(i,0,1);
    	for(re int i=2;i<=cnt;i++) ans+=len[i]-len[fa[i]];
    	printf("%lld
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    web前段学习2017.6.15
    web前段学习2017.6.13
    web前端2017.6.10
    web前段2017.6.8
    web前段学习2016.6.6
    宏任务与微任务
    浏览器兼容性问题
    TCP 和 UDP 的区别
    React如何渲染大数据量的列表?
    移动端兼容性问题
  • 原文地址:https://www.cnblogs.com/asuldb/p/10266828.html
Copyright © 2011-2022 走看看