ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

luogu4323 独特的树叶

2021-09-14 11:01:02  阅读:185  来源: 互联网

标签:prime sizz 树叶 int siz luogu4323 fa maxn 独特


题目描述

JYY有两棵树 A 和 B :树 A 有 N 个点,编号为 1 到 N ;树 B 有N+1 个节点,编号为 1 到N+1

JYY 知道树 B 恰好是由树 A 加上一个叶节点,然后将节点的编号打乱后得到的。他想知道,这个多余的叶子到底是树 B 中的哪一个叶节点呢?

输入格式

输入一行包含一个正整数 N。 接下来 N−1 行,描述树A,每行包含两个整数表示树 A 中的一条边; 接下来 N 行,描述树 B,每行包含两个整数表示树 B 中的一条边。

输出格式

输出一行一个整数,表示树 B 中相比树 A 多余的那个叶子的编号。如果有多个符合要求的叶子,输出 B 中编号最小的那一个的编号。

输入输出样例

输入

5
1 2
2 3
1 4
1 5
1 2
2 3
3 4
4 5
3 6

输出

1

说明/提示

对于所有数据,\(1 \leq n \leq 10 ^ 5\)


求出A树中所有点为根的树哈希值,并排序!
求出B树中所有点为根的树哈希值,从小到大枚举每一个叶子,如果它连接的点的哈希值减去这个叶子对它的贡献(为2)可以在A树所有哈希值中找到则输出,并结束程序!


#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
struct edge
{
	int u,v,nxt;
}e[maxn<<1],ee[maxn<<1];
int head[maxn],js,headd[maxn],jss;
void addage(int u,int v)
{
	e[++js].u=u;e[js].v=v;
	e[js].nxt=head[u];head[u]=js;
}
void addagee(int u,int v)
{
	ee[++jss].u=u;ee[jss].v=v;
	ee[jss].nxt=headd[u];headd[u]=jss;
}
int n;
bool noprime[(int)2e6+10];
int prime[maxn],cnt;
void getprime()
{
	for(int i=2;i<2e6+10;++i)
	{
		if(cnt>n)return;
		if(!noprime[i])prime[++cnt]=i;
		for(int j=1;j<=cnt;++j)
		{
			if(i*prime[j]>2e6)break;
			noprime[i*prime[j]]=1;
			if(i%prime[j]==0)break;
		}
	}	
}
int f[maxn],siz[maxn],g[maxn];
void dfs(int u,int fa)
{
	f[u]=siz[u]=1;
	for(int i=head[u];i;i=e[i].nxt)
	{
		int v=e[i].v;
		if(v==fa)continue;
		dfs(v,u);
		siz[u]+=siz[v];
		f[u]+=f[v]*prime[siz[v]];
	}
}
void getg(int u,int fa,int faf)
{
	for(int i=head[u];i;i=e[i].nxt)
	{
		int v=e[i].v;
		if(v==fa)continue;
		int tp=f[u]-f[v]*prime[siz[v]]+faf*prime[n-siz[u]];
		g[v]=f[v]+tp*prime[n-siz[v]];
		getg(v,u,tp);
	}
}
int ff[maxn],sizz[maxn],gg[maxn];
void dfss(int u,int fa)
{
	ff[u]=sizz[u]=1;
	for(int i=headd[u];i;i=ee[i].nxt)
	{
		int v=ee[i].v;
		if(v==fa)continue;
		dfss(v,u);
		sizz[u]+=sizz[v];
		ff[u]+=ff[v]*prime[sizz[v]];
	}
}
void getgg(int u,int fa,int faf)
{
	for(int i=headd[u];i;i=ee[i].nxt)
	{
		int v=ee[i].v;
		if(v==fa)continue;
		int tp=ff[u]-ff[v]*prime[sizz[v]]+faf*prime[n+1-sizz[u]];
		gg[v]=ff[v]+tp*prime[n+1-sizz[v]];
		getgg(v,u,tp);
	}
}
int du[maxn],mnd[maxn];
int main()
{
	scanf("%d",&n);
	getprime();
	for(int u,v,i=1;i<n;++i)
	{
		scanf("%d%d",&u,&v);
		addage(u,v);addage(v,u);
	}
	for(int u,v,i=1;i<=n;++i)
	{
		scanf("%d%d",&u,&v);
		addagee(u,v);addagee(v,u);
		++du[u];++du[v];
	}
	dfs(1,0);
	g[1]=f[1];
	getg(1,0,0);
	sort(g+1,g+1+n);
	dfss(1,0);
	gg[1]=ff[1];
	getgg(1,0,0);
	for(int u=1;u<n+1;++u)
	{
		if(du[u]!=1)continue;
		int i=headd[u];
		int w=gg[ee[i].v]-2;
		int tp=lower_bound(g+1,g+1+n,w)-g;
		if(tp>n)continue;
		if(g[tp]==w)
		{
			printf("%d",u);
			return 0;
		}
	}
	return 0;
}

标签:prime,sizz,树叶,int,siz,luogu4323,fa,maxn,独特
来源: https://www.cnblogs.com/gryzy/p/15266576.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有