记录编号 160083 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 [ZJOI 2015]诸神眷顾的幻想乡 最终得分 100
用户昵称 Gravatarcstdio 是否通过 通过
代码语言 C++ 运行时间 2.795 s
提交时间 2015-04-23 19:29:38 内存使用 17.86 MiB
显示代码纯文本
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
typedef long long LL;
#define Nil NULL
const int SIZEN=100010;
const int SIZE_SAM=100000*2*20+10;
class Node{
public:
	int len;
	Node *suflink;
	Node *ch[10];
	void clear(void){
		len=0;
		suflink=Nil;
		memset(ch,0,sizeof(ch));
	}
	Node(void){clear();}
};
class Suffix_Automaton{
public:
	Node *root;
	int n;
	Node *lis[SIZE_SAM];
	int findpos(Node *a){
		if(a==Nil) return -1;
		for(int i=0;i<n;i++){
			if(lis[i]==a) return i;
		}
		return -2;
	}
	void print(Node *a){
		cout<<"地址: "<<findpos(a)<<endl;
		cout<<"len: "<<a->len<<endl;
		cout<<"suflink: "<<findpos(a->suflink)<<endl;
		for(int i=0;i<10;i++){if(a->ch[i]!=Nil){cout<<i<<" : "<<findpos(a->ch[i])<<endl;}}
		cout<<endl;
	}
	Node* new_Node(void){//新创立一个长度为l的节点
		Node *p=new Node;
		lis[n++]=p;
		return p;
	}
	void clear(void){
		n=0;
		root=new_Node();
	}
	Suffix_Automaton(void){clear();}
	LL calc(void){
		LL ans=0;
		for(int i=1;i<n;i++){
			Node *p=lis[i];
			ans+=p->len-p->suflink->len;
		}
		return ans;
	}
	Node* insert(Node *last,int k){
		//===和普通SAM的区别之处===
		Node *cur=last->ch[k];
		if(cur!=Nil&&cur->len==last->len+1) return cur;
		else{
			cur=new_Node();
			cur->len=last->len+1;
		}
		//=========================
		Node *p=last;
		while(p!=Nil&&p->ch[k]==Nil){
			p->ch[k]=cur;
			p=p->suflink;
		}
		if(p==Nil) cur->suflink=root;
		else{
			Node *q=p->ch[k];
			if(p->len+1==q->len) cur->suflink=q;
			else{
				Node *clone=new_Node();
				*clone=*q;
				clone->len=p->len+1;
				cur->suflink=clone;
				q->suflink=clone;
				while(p!=Nil&&p->ch[k]==q){
					p->ch[k]=clone;
					p=p->suflink;
				}
			}
		}
		return cur;
	}
}MT;
int N,C;
int color[SIZEN]={0};
vector<int> G[SIZEN];
int deg[SIZEN]={0};
Node* pos[SIZEN];
void DFS(int x,int fa){
	pos[x]=MT.insert(pos[fa],color[x]);
	for(int i=0;i<G[x].size();i++){
		int u=G[x][i];
		if(u!=fa) DFS(u,x);
	}
}
void work(void){
	pos[0]=MT.root;
	for(int i=1;i<=N;i++){
		if(deg[i]==1) DFS(i,0);
	}
	cout<<MT.calc()<<endl;
}
void read(void){
	scanf("%d%d",&N,&C);
	for(int i=1;i<=N;i++) scanf("%d",&color[i]);
	int a,b;
	for(int i=1;i<N;i++){
		scanf("%d%d",&a,&b);
		G[a].push_back(b);
		G[b].push_back(a);
		deg[a]++,deg[b]++;
	}
}
int main(){
	freopen("zjoi15_substring.in","r",stdin);
	freopen("zjoi15_substring.out","w",stdout);
	read();
	work();
	return 0;
}