记录编号 307269 评测结果 AAAAAATATA
题目名称 树上的游戏 最终得分 80
用户昵称 Gravatar农场主 是否通过 未通过
代码语言 C++ 运行时间 8.544 s
提交时间 2016-09-14 14:57:59 内存使用 36.34 MiB
显示代码纯文本
#include <iostream>
#include <cstdio>
#include <vector>
#define pb push_back
using namespace std;
const int nmax=400086;
const int vmax=20;
int n,q;
int s=0;
int tmpu,tmpv;
int au,av;
int tmpnode;
int predeep;
int smin[nmax][vmax];
int list[nmax];
int pos[nmax],deep[nmax];
bool vis[nmax];
class edge
{
public:
	int u,v;
};
vector<edge> edges;
vector<int > G[nmax];
inline void PreDo()
{
	scanf("%d",&n);
	deep[0]=0;
	for(int i=1;i<=n-1;i++)
	{
		scanf("%d%d",&tmpu,&tmpv);
		edges.pb((edge){tmpu,tmpv});
		G[tmpu].pb(edges.size()-1);
		edges.pb((edge){tmpv,tmpu});
		G[tmpv].pb(edges.size()-1);
	}

}
void DFS(int x)
{
	vis[x]=1;
	s++;
	list[s]=x;
	pos[x]=s;
	for(int i=0;i<G[x].size();i++)
	{
		if(vis[edges[G[x][i]].v]==0)
		{
			deep[edges[G[x][i]].v]=deep[edges[G[x][i]].u]+1;
			DFS(edges[G[x][i]].v);
			s++;
			list[s]=x;
		}
	}
}

inline int minx(int a,int b)
{
	if(deep[a]<deep[b])
		return a;
	else
		return b;
}

inline void RMQ()
{
	for(int i=1;i<=s;i++)
		smin[i][0]=list[i];
	for(int j=1;j<vmax;j++)
		for(int i=1;i<=s;i++)
			if(i+(1<<j)-1<=s)
				smin[i][j]=minx(smin[i][j-1],smin[i+(1<<(j-1))][j-1]);
}
inline void exchangea(int &tmpu,int &tmpv)
{
	if(pos[tmpu]>pos[tmpv])
	{
		int tmp;
		tmp=tmpu;
		tmpu=tmpv;
		tmpv=tmp;
	}
}
inline void exchangeu(int &nodeu,int &nodelca)
{
	if(pos[nodeu]>pos[nodelca])
	{
		int tmp;
		tmp=nodeu;
		nodeu=nodelca;
		nodelca=tmp;
	}
}
inline void exchangev(int &nodev,int &nodelca)
{
	if(pos[nodev]>pos[nodelca])
	{
		int tmp;
		tmp=nodev;
		nodev=nodelca;
		nodelca=tmp;
	}
}
inline int log2(int x){
	int t=1;
	int tot=0;
	while (1){
		if (t>x) return tot-1;
		t=t<<1;
		tot++;
	}
}
inline int LCA(int x,int y)//传入的是某编号的节点对应的位置
{
	if(y<x)
	{
		int tmp=y;
		y=x;
		x=tmp;
	}
	int k=log2(y-x+1);
	int lca=minx(smin[x][k],smin[y-(1<<k)+1][k]);
	return lca;
}
inline void exchange()
{
	if(pos[tmpu]>pos[tmpv])
	{
		int tmp=tmpu;
		tmpu=tmpv;
		tmpv=tmp;
	}
}

int main()
{
	//printf("%d",log2(3));
	freopen("treegame.in","r",stdin);
	freopen("treegame.out","w",stdout);
	PreDo();
	DFS(1);
	RMQ();
	scanf("%d",&q);
	for(int i=1;i<=q;i++)
	{
		scanf("%d%d%d",&au,&av,&tmpnode);
		int lcanode=LCA(pos[au],pos[av]);
		//printf("%d\n",lcanode);
		int du=edges[tmpnode*2-2].u;
		int dv=edges[tmpnode*2-2].v;
		int predeep;
		if(deep[du]<deep[dv])
			predeep=du;
		else
			predeep=dv;
		int lcalca=LCA(pos[lcanode],pos[predeep]);
		if(lcalca!=lcanode)
		{
			printf("YES\n");
		}
		else
		{
			int lcalu=LCA(pos[au],pos[du]);
			int lcalv=LCA(pos[au],pos[dv]);
			int lcaru=LCA(pos[av],pos[du]);
			int lcarv=LCA(pos[av],pos[dv]);
			if(lcalu==du&&lcalv==dv)
				printf("NO\n");
			else
			{
				if(lcaru==du&&lcarv==dv)
					printf("NO\n");
				else
					printf("YES\n");
			}
		}
	}
	return 0;
}