[JSOI2016]
- 那么我们考虑一下用异或+子树大小的方式结合Hash的进制规则来做。
- 设计Hash函数为H[x]=\xor H[y]*p+size[y]
- 那么我们只要先求出以某个点为根时的Hash值,然后在递推到每一个点为根的情况即可(换根树形DP),这个直接用异或的性质异或回去抵消即可。
- unsigned long long不影响异或
Code
#include<bits/stdc++.h>
#include<tr1/unordered_map>
#define rep(i,a,b) for(register int i=(a);i<=(b);++i)
#define ull unsigned long long
using namespace std;
const int N=1e5+5;
const ull p=2333333;
struct node{int y,n;}e[N<<1];
int lin[N<<1],size[N],fa[N],d[N],a[N],root,cut,cnt,len,n,x,y;
ull h[N],val[N];
std::tr1::unordered_map<ull,int> v;
inline void read(int x,int y){e[++len].y=y,e[len].n=lin[x],lin[x]=len;}
inline int read(){
int num=0;char ch=getchar();
while(!isdigit(ch))ch=getchar();
while(isdigit(ch))num=num*10+ch-'0',ch=getchar();
return num;
}
void dfs1(int x,int f){
size[x]=1;
for(int i=lin[x];i;i=e[i].n){
int y=e[i].y;
if(y==f)continue;
dfs1(y,x);
size[x]+=size[y];
h[x]^=h[y]*p+size[y];
}
}
void dfs2(int x,int f,int root){
if(x!=root)val[x]=h[x]^((val[f]^(h[x]*p+size[x]))*p+n-size[x]);
for(int i=lin[x];i;i=e[i].n){
int y=e[i].y;
if(y==f)continue;
dfs2(y,x,root);
}
}
void dfs3(int x,int f){
size[x]=1,h[x]=0;fa[x]=f;
for(int i=lin[x];i;i=e[i].n){
int y=e[i].y;
if(y==f)continue;
dfs3(y,x);
size[x]+=size[y];
h[x]^=h[y]*p+size[y];
}
}
int main()
{
//freopen("a.in","r",stdin);
n=read();
rep(i,2,n){
x=read(),y=read();
read(x,y),read(y,x);
}
dfs1(1,0);
val[1]=h[1],dfs2(1,0,1);
rep(i,1,n)v[val[i]]=1;
memset(lin,0,sizeof(lin)),len=0;
n++;
rep(i,2,n){
x=read(),y=read();
read(x,y),read(y,x);
d[x]++,d[y]++;
}
rep(i,1,n)if(d[i]==1)a[++cnt]=i;else root=i;
dfs3(root,0);
val[root]=h[root];
dfs2(root,0,root);
rep(i,1,cnt){
cut=a[i];
if(v.count(val[fa[cut]]^1)){
printf("%d",cut);
return 0;
}
}return 0;
}