http://www.lydsy.com/JudgeOnline/problem.php?id=3319
Test instructions: to a tree of n nodes (N<=1e6), M Operations (M<=1E6), each operation has two kinds: 1, query U to the root of the first black edge number. 2. Dye the path from u to v Black
#include <cstdio> #include <cstring> #include <cmath> #include <string> #include <iostream > #include <algorithm> #include <queue> #include <set> #include <map> #include <sstream >using namespace Std;typedef long long ll; #define PB Push_back#define Rep (i, n) for (int i=0; i< (n); ++i) #define For1 (i,a,n) for (int i= (a), i<= (n), ++i) #define FOR2 (i,a,n) for (int i= (a);i< (n), ++i) #define FOR3 (i,a,n) for (int i= (a); I >= (n); i) #define FOR4 (i,a,n) for (int i= (a);i> (n); i) #define CC (i,a) memset (i,a,sizeof (i)) #define READ (a) a= Getint () #define PRINT (a) printf ("%d", a) #define DBG (x) cout << (#x) << "=" << (x) << Endl#define Error (x) (! ( x) puts ("error"): 0) #define RDM (x, i) for (int i=ihead[x]; i; i=e[i].next) inline int getint () {static int r, K; r=0,k=1; St Atic Char C; C=getchar (); for (; c< ' 0 ' | | C> ' 9 '; C=getchar ()) if (c== '-') k=-1; for (; c>= ' 0 ' &&c<= ' 9 '; C=getchar ()) r=r*10+c-' 0 '; return k*r; }const int N=1e6+10;int lca[n], fa[n], dep[n], id[n], N, del[n];struct Un {int f[n];void init () {For1 (i, 1, N) f[i]=i;} int find (int x) {return x==f[x]?x:f[x]=find (f[x]);} void U (int x, int y) {x=find (x); Y=find (y); if (Dep[x]<dep[y]) swap (x, y); f[x]=y;}}; struct Gr {int ihead[n], cnt;struct dat {int Next, from, to, id;} e[n<<1];void Add (int u, int v, int id) {e[++cnt].next=ihead[u]; ihead[u]=cnt; e[cnt].from=u; e[cnt].to=v; e[cnt].id =ID;E[++CNT].NEXT=IHEAD[V]; ihead[v]=cnt; E[cnt].from=v; E[cnt].to=u; E[cnt].id=id;} void Add1 (int u, int v) {e[++cnt].next=ihead[u]; ihead[u]=cnt; e[cnt].to=v;} void Tarjan (int x, Gr &g) {static bool vis[n];static Un P;P.F[X]=X;RDM (x, i) if (E[i].to!=fa[x]) {dep[e[i].to]=dep[x]+ 1; Fa[e[i].to]=x; Id[e[i].to]=i; Tarjan (E[i].to, G); P.f[e[i].to]=x; }vis[x]=1;for (int i=g.ihead[x]; i; i=g.e[i].next) if (vis[g.e[i].to]) lca[g.e[i].id]=p.find (g.e[i].to);}} G, ask, G; Un F, temp;void split (int u, int v, int goal, int now) {for (U=temp.find (u); dep[u]>dep[Goal]; Del[u]=1, temp. U (U, Fa[u]), G.ADD1 (now, Id[u]), U=temp.find (Fa[u])); for (V=temp.find (v); dep[v]>dep[goal]; del[v]=1, temp. U (V, Fa[v]), G.ADD1 (now, Id[v]), V=temp.find (Fa[v]));} void link (int u, int v, int goal, int now) {for (int i=g.ihead[now]; i; i=g.e[i].next) f.u (G.e[g.e[i].to].from, G.e[g.e[i]. to].to);} struct Q {int flag, u, V;} Q[n];int M;int Main () {read (N); read (m); For1 (i, 1, n-1) G.add (Getint (), Getint (), i), For1 (i, 1, m) {read (Q[i].flag); Read ( Q[I].V); if (q[i].flag==2) {read (Q[I].U); Ask.add (q[i].u, Q[I].V, i);}} G.tarjan (1, ask); Temp.init (); F.init (); For1 (i, 1, m) if (q[i].flag==2) {split (q[i].u, Q[I].V, lca[i], i);} For1 (i, 1, m) if (q[i].flag==2) {//printf ("g[%d]:", I);//for (int j=g.ihead[i]; J J=g.e[j].next) printf ("(%d<->%d),", G.e[g.e[j].to].from, g.e[g.e[j].to].to); Puts ("");//}for1 (I, 2, N) if (!del[i]) f.u (i, fa[i]), static int out[n], Num=0;for3 (i, M, 1) {if (q[i].flag==1) {int ans=f. Find (Q[I].V); if (ans==1) out[++num]=0; else out[++num]=g.e[id[ans]].iD }else {link (q[i].u, Q[I].V, lca[i], i);}} For3 (i, NUM, 1) printf ("%d\n", Out[i]); return 0;}
Good God's problem spicy ....
I wrote a long-ago chain-cut + line tree ... Decisive tle ... ("Bzoj" 3319: Black-and-white tree (and check set + special tricks/-tree chain + line tree))
Then long ago also saw Claris Master of the puzzle, good god Qaq
He said it is offline, then I went down the line thinking of the next ...
First, it is found that the stain is corresponding to the deleted edge ... The children who represent the points on the edge do not need to be ancestors of this point ...
Then find the number of each query is the current most recent ancestor ....
Then consider how to delete the edge ... At first I was directly open and check the set of the mess ... But on my knees ... In fact, you only need to find and check the root of the set in the deleted place and then go up, note to delete the edges recorded, otherwise you will not be able to merge
Then consider how to merge ... Discover that we only need to determine the final shape of the tree, and then join the previously deleted edges. So that is to say, will be asked to go offline, from the back forward, if it is asked to directly ask the root of the current collection, or before merging in this operation deleted edge
Then it's all right, Qaq.
"Bzoj" 3319: Black and White Tree