2019.01.01【ZJOI2015】【BZOJ3629】【洛谷P3346】诸神眷顾的幻想乡(广义SAM)

版权声明:转载请声明出处,谢谢配合。 https://blog.csdn.net/zxyoi_dreamer/article/details/85553144

BZOJ传送门

洛谷传送门


解析:

裸的广义SAM,其实广义SAM在构建的时候与SAM的差别就是需要传递一个原来的父亲节点编号,其他就没什么了。

这道题要统计不同的字串个数,直接每个节点 l e n u l e n f a u len_u-len_{fa_u} 就是这个节点对于它的父亲产生的新的子串个数,然后。。。就没有然后了。。。


代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define re register
#define gc get_char
#define pc putchar
#define cs const

namespace IO{
	namespace IOONLY{
		cs int Rlen=1<<18|1;
		char buf[Rlen],*p1,*p2;
	}
	inline char get_char(){
		using namespace IOONLY;
		return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,Rlen,stdin),p1==p2)?EOF:*p1++;
	}
	
	inline int getint(){
		re int num;
		re char c;
		while(!isdigit(c=gc()));num=c^48;
		while(isdigit(c=gc()))num=(num+(num<<2)<<1)+(c^48);
		return num;
	}
}
using namespace IO;

cs int N=1000006;
vector<int> edge[N];
inline void addedge(int u,int v){
	edge[u].push_back(v);
	edge[v].push_back(u);
}

int n,C;
struct SAM{
	int fa[N<<1],len[N<<1],son[N<<1][12];
	int last,now;
	SAM():last(1),now(1){}
	inline int push_back(int c,int p){
		int cur=++now;
		len[cur]=len[p]+1;
		for(;p&&!son[p][c];p=fa[p])son[p][c]=cur;
		if(!p)fa[cur]=1;
		else if(len[son[p][c]]==len[p]+1)fa[cur]=son[p][c];
		else {
			int clone=++now,q=son[p][c];
			len[clone]=len[p]+1;
			memcpy(son[clone],son[q],sizeof son[q]);
			fa[clone]=fa[q];
			fa[q]=fa[cur]=clone;
			for(;p&&son[p][c]==q;p=fa[p])son[p][c]=clone;
		}
		return cur;
	}
	
	inline ll calc(){
		re ll res=0;
		for(int re i=2;i<=now;++i)res+=len[i]-len[fa[i]];
		return res;
	}
}sam;

int val[N];
inline void dfs(int u,int fa,int p){
	int cur=sam.push_back(val[u],p);
	for(int re e=0;e<edge[u].size();++e)
	if(edge[u][e]^fa)dfs(edge[u][e],u,cur);
}

signed main(){
	n=getint();
	C=getint();
	for(int re i=1;i<=n;++i)val[i]=getint();
	for(int re i=1;i<n;++i)addedge(getint(),getint());
	for(int re i=1;i<=n;++i)if(edge[i].size()==1)dfs(i,0,1);
	printf("%lld",sam.calc());
	return 0;
}

猜你喜欢

转载自blog.csdn.net/zxyoi_dreamer/article/details/85553144