2015-10-07 20:44:42
题意问的是给了一颗树,然后又1000000次查询u,v,问不在树路径上的点的编号最小值,以1为根 建这颗树,然后在同一棵子树中的点子让就输出1 否则我们记录每个点从离1最近的那个点也就是1的孩子,到该点所经过的最小值,以及在他父亲到1的孩子,这段间和他不在同一条叉到上的最小值,还有就是他子树的最小值,然后遍历一遍,每次查询的时候搞一下就好了
#include <iostream> #include <algorithm> #include <cstdio> #include <string.h> using namespace std; const int maxn=1000005; template <class T> inline bool rd(T &ret) { char c; int sgn; if (c = getchar(), c == EOF) return 0; while (c != '-' && (c<'0' || c>'9')) c = getchar(); sgn = (c == '-') ? -1 : 1; ret = (c == '-') ? 0 : (c - '0'); while (c = getchar(), c >= '0'&&c <= '9') ret = ret * 10 + (c - '0'); ret *= sgn; return 1; } template <class T> inline void pt(T x) { if (x <0) { putchar('-'); x = -x; } if (x>9) pt(x / 10); putchar(x % 10 + '0'); } int fa[maxn],H[maxn],to[maxn*2],nx[maxn*2],numofE; int upMIN[maxn],downMIN[maxn][2],other[maxn]; int belong[maxn]; void init(int N){ numofE=0; memset(H,0,sizeof(H)); } void add(int u,int v) { numofE++; to[numofE]=v; nx[numofE]=H[u]; H[u]=numofE; } int Q[maxn]; void cmp(int O,int a){ if(a<downMIN[O][0]){ downMIN[O][1]=downMIN[O][0]; downMIN[O][0]=a; }else if(a<downMIN[O][1]){ downMIN[O][1]=a; } } void searchroot(int cur) { int rear=0; Q[rear++]=cur; fa[cur]=1; belong[cur]=cur; upMIN[cur]=cur; for(int i=0; i<rear; i++) { int x=Q[i]; other[x]=downMIN[x][0]=downMIN[x][1]=maxn; for(int j=H[x]; j; j=nx[j]) { int too=to[j]; if(too==fa[x])continue; Q[rear++]=too; fa[too]=x; upMIN[too]=min(too,upMIN[x]); belong[too]=cur; } } for(int i=rear-1; i>=0; i--) { int x=Q[i]; for(int j=H[x]; j; j=nx[j]) { int too=to[j]; if(too==fa[x])continue; int a=min(too,downMIN[too][0]); cmp(x,a); } } for(int i=1; i<rear; i++){ int x=Q[i]; int a=min(x,downMIN[x][0]); int f=fa[x]; if(a!=downMIN[f][0]){ other[x]=min(other[f],downMIN[f][0]); }else{ other[x]=min(other[f],downMIN[f][1]); } } } int A[4],B[5]; void jud(int a) { A[3]=a; for(int i=2; i>=0; i--) if(A[i]>A[i+1])swap(A[i],A[i+1]); else break; } void solve1(int a,int b) { for(int i=0; i<3; i++) if(A[i]!=a&&A[i]!=b){ B[0]=A[i];return ; } } int jud2() { int v=B[0]; for(int i=1;i<5;i++) v=min(B[i],v); return v; } int main() { int N,q; downMIN[1][0]=downMIN[1][1]=other[1]=upMIN[1]=maxn; while(scanf("%d%d",&N,&q)==2) { init(N); for(int i=1; i<N; i++) { int a,b; rd(a);rd(b); add(a,b);add(b,a); } A[0]=A[1]=A[2]=maxn; for(int i=H[1]; i; i=nx[i]) { searchroot(to[i]); jud(min(to[i],downMIN[to[i]][0])); } int d=0; for(int i=0; i<q; i++) { int a,b; rd(a);rd(b); a^=d;b^=d; if(a==1&&b==1){ d=2; puts("2");continue; } if(belong[a]==belong[b]){ d=1; puts("1");continue; } if(a==1||b==1){ a=max(a,b);b=max(a,b); } solve1(upMIN[a],upMIN[b]); B[1]=other[a];B[2]=other[b]; B[3]=downMIN[a][0];B[4]=downMIN[b][0]; d=jud2(); printf("%d ",d); } } return 0; }