HDU 4916(Count on the path-树上除链上的节点外最小值[强制在线])

Count on the path

Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 866    Accepted Submission(s): 219


Problem Description
bobo has a tree, whose vertices are conveniently labeled by 1,2,…,n.

Let f(a,b) be the minimum of vertices not on the path between vertices a and b.

There are q queries (u i,v i) for the value of f(u i,v i). Help bobo answer them.
 

Input
The input consists of several tests. For each tests:

The first line contains 2 integers n,q (4≤n≤10 6,1≤q≤10 6). Each of the following (n - 1) lines contain 2 integers a i,b i denoting an edge between vertices a i and b i (1≤a i,b i≤n). Each of the following q lines contains 2 integer u′ i,v′ i (1≤u i,v i≤n).

The queries are encrypted in the following manner.

u 1=u′ 1,v 1=v′ 1.
For i≥2, u i=u′ i⊕f(u i - 1,v i - 1),v i=v′ i⊕f(u i-1,v i-1).

Note ⊕ denotes bitwise exclusive-or.

It is guaranteed that f(a,b) is defined for all a,b.

The task contains huge inputs. `scanf` in g++ is considered too slow to get accepted. You may (1) submit the solution in c++; or (2) use hand-written input utilities.
 

Output
For each tests:

For each queries, a single number denotes the value.
 

Sample Input
   
   
   
   
4 1 1 2 1 3 1 4 2 3 5 2 1 2 1 3 2 4 2 5 1 2 7 6
 

Sample Output
   
   
   
   
4 3 1
 

Author
Xiaoxu Guo (ftiasch)
 

Source
2014 Multi-University Training Contest 5
 

Recommend
We have carefully selected several similar problems for you:   5426  5425  5424  5423  5422 
 


HDU 4916(Count on the path-树上除链上的节点外最小值[强制在线])_第1张图片




#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<functional>
#include<cmath>
#include<algorithm>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=pre[x];p;p=Next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])  
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (100000007)
#define pb push_back
#define mp make_pair 
#pragma comment(linker, "/STACK:102400000,102400000")
#define MAXN (2000000+10)
typedef long long ll;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return (a-b+llabs(a-b)/F*F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}

int edge[MAXN],pre[MAXN],Next[MAXN],siz=1;
void addedge(int u,int v)
{
	edge[++siz]=v;
	Next[siz]=pre[u];
	pre[u]=siz;
}
void addedge2(int u,int v){addedge(u,v); addedge(v,u); }

int minv[MAXN],fa[MAXN],f[MAXN],g[MAXN];
void dfs(int x,int u){
	g[x]=INF;
	Forp(x) {
		int v=edge[p];
		if (v==u) continue;
		fa[v]=x; dfs(v,x); 
		g[x]=min(g[x],minv[v]);
	}
	
	minv[x]=min(x,g[x]);
} 
int bel[MAXN]; 
void bel_fill(int x,int bel_c)
{
	bel[x]=bel_c;
	Forp(x) {
		int v=edge[p];
		if (v==fa[x]) continue;
		bel_fill(v,bel_c);
	}
	
}
void dfs2(int x) 
{
	int d1=INF,d2=INF;
	Forp(x) {
		int v=edge[p];
		if (v==fa[x]) continue;
		if (minv[v]<d1) d2=d1,d1=minv[v];
		else if (minv[v]<d2) d2=minv[v];
	}
	Forp(x) {
		int v=edge[p];
		if (v==fa[x]) continue;
		f[v]=f[x];
		if (x^1) {
			if (minv[v]==d1) f[v]=min(f[v],d2);
			else f[v]=min(f[v],d1); 
		}
		dfs2(v);
		
	}
}
int main()
{
//	freopen("hdu4916.in","r",stdin);
//	freopen(".out","w",stdout);
	
	int n,q;
		
	while(scanf("%d%d",&n,&q)==2) {
		
		MEM(edge) MEM(pre) MEM(Next) siz=1;
		MEMI(f) MEMI(g) MEM(fa) MEMI(minv) MEM(bel)
		For(i,n-1) {
			int u,v;
			scanf("%d%d",&u,&v);
			addedge2(u,v);
		}
		
		dfs(1,0);
		dfs2(1);
		Forp(1){
			int v=edge[p];
			bel_fill(v,v);								
		}
		
		int ans=0;
		For(i,q) {
			int u,v;
			scanf("%d%d",&u,&v);
			u^=ans;v^=ans;
			if(u>v) swap(u,v);
			if (bel[u]==bel[v]&&bel[u]!=0) ans=1;
			else if (u==v&&u==1) ans=2;
			else {
				if (u==1) ans=min(f[v],g[v]);
				else ans=min(min(f[u],g[u]),min(f[v],g[v]));
				Forp(1) {					
					if (bel[u]!=edge[p]&&bel[v]!=edge[p]) ans=min(ans,minv[edge[p]]);
				}
			}
			
			printf("%d\n",ans);			
		}
		
		
	}
	
	
	return 0;
}




你可能感兴趣的:(HDU 4916(Count on the path-树上除链上的节点外最小值[强制在线]))