"Bzoj" 3319: Black and White Tree

Source: Internet
Author: User

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

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.