P4323
题目传送门
题目梗概
在
题意分析
题目要求我们对比两颗树是否一样,暴力算法
对于一个节点
为了方便找到,我们先维护以变
上代码
#include<bits/stdc++.h>
#define ull unsigned long long
#define int ull
using namespace std;
const int maxn=2e6+5;
struct node{
int to,nxt;
}ed[maxn];
int head[maxn<<1];
int n,tot,siz[maxn];
ull f[maxn],g[maxn];
int prime[maxn];
int io[maxn];
int fa[maxn];
bool isprime[maxn];
set<int> st;
void add(int u,int v){
ed[++tot].to=v;
ed[tot].nxt=head[u];
head[u]=tot;
}
void er(int n){
memset(isprime,true,sizeof(isprime));
prime[0]=0;
for(int i=2;i<=n;i++){
if (isprime[i])prime[++prime[0]]=i;
for(int j=1;j<=prime[0] && i*prime[j]<=n;j++){
isprime[i*prime[j]]=false;
if (i%prime[j]==0) break;
}
}
}
void dfs(int u,int fa){
siz[u]=1;
f[u]=1;
for(int i=head[u];i;i=ed[i].nxt){
int to=ed[i].to;
if(to==fa) continue;
dfs(to,u);
siz[u]+=siz[to];
f[u]+=f[to]*prime[siz[to]];
}
}
void dfs1(int u,int fa,int tmp){
g[u]=f[u]+tmp*prime[n-siz[u]];
for(int i=head[u];i;i=ed[i].nxt){
int to=ed[i].to;
if(to==fa) continue;
int temp=g[u]-f[to]*prime[siz[to]];
dfs1(to,u,temp);
}
}
void init(){
tot=0;
memset(head,0,sizeof head);
memset(g,0,sizeof(g));
memset(f,0,sizeof f);
memset(siz,0,sizeof siz);
}
main(){
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
cin>>n;
er(1299710);
for(int a,b,i=1;i<n;i++){
cin>>a>>b;
add(a,b);add(b,a);
}
dfs(1,0);
dfs1(1,0,0);
for(int i=1;i<n;i++){
st.insert(g[i]);
}
init();
n++;//本人代码在此挂了3次
//因为dfs 和 dfs1会用到n,所以n必须更新为当前节点数
for(int a,b,i=1;i<n;i++){
cin>>a>>b;
add(a,b);add(b,a);
io[a]++,io[b]++;
}
dfs(1,0);
dfs1(1,0,0);
for(int i=1;i<=n;i++){
if(io[i]!=1) continue;
int fo=(g[ed[head[i]].to]-2);
if(st.find(fo)!=st.end()){
cout<<i<<'\n';
return 0;
}
}
return 0;
}