bzoj1095 [zjoi2007]hide Hide and Seek
Original title address : http://www.lydsy.com/JudgeOnline/problem.php?id=1095
Test Instructions:
Given a tree of n nodes, all the nodes are initially black.
There are two actions for m operations:
C x:x node Inverse color
G: The distance between the furthest two black point pairs in the query tree
Data Range
n≤100000, m≤500000.
The following:
The static and the Pat have been looked at for a long while, finally finally to shoot out:
3
1 2
2 3
6
C 1
G
C 1
G
C 3
G
Alas.
First dynamic Point division.
Several errors were found:
At the beginning of the construction of the tree when the heap was pushed wrong, the center is also a problem to find.
Later, when the heap is empty, it writes the B heap, which is actually a heap.
Not only diligent comments, their own color every statement should be clear is.
This maintenance del heap to delete operations accumulates.
Code:
#include <cstdio> #include <iostream> #include <cstring> #include <algorithm> #include <
Queue> using namespace std;
const int n=100010;
const int m=1000005;
const int P=20;
int n,m,tot=0,head[n],to[m],nxt[m],num=0,col[n],fa[n],size[n],ss[n],sz=0,root=0,dep[n],anc[n][p+3],cnt;
BOOL Del[n];
struct PQ {priority_queue<int> q,del;
void Insert (int x) {q.push (x);}
void Pop () {while (!del.empty () &&q.top () ==del.top ()) {Q.pop (); Del.pop ();} q.pop ();}
int Top () {while (!del.empty () &&q.top () ==del.top ()) {Q.pop (); Del.pop ();}
return Q.top ();
} int sectop () {int u=top (); pop (); int Ret=top ();
Insert (U);
return ret;
} void Erase (int x) {del.push (x);} int size () {return q.size ()-del.size ();}}
A[n],b[n],c; /* * Heap a--distance from sons to Father * Heap b--contributions of all sons tops from A * Heap c--answers Altoget She tops and sectops from B */void Dfs (intU,int f) {anc[u][0]=f;
for (int i=1;i<p;i++) anc[u][i]=anc[anc[u][i-1]][i-1];
dep[u]=dep[f]+1;
for (int i=head[u];i;i=nxt[i]) {int v=to[i];
if (v==f) continue;
DFS (V,U);
}} int LCA (int u,int v) {if (Dep[u]<dep[v]) swap (U,V);
int D=DEP[U]-DEP[V];
for (int i=0;d;d>>=1,i++) if (d&1) u=anc[u][i];
if (u==v) return u;
for (int i=p-1;i>=0;i--) if (Anc[u][i]!=anc[v][i]) {u=anc[u][i]; v=anc[v][i];}
return anc[u][0];
} void Build (int u,int v) {num++;
To[num]=v;
Nxt[num]=head[u];
Head[u]=num;
} void Getroot (int u,int f) {size[u]=1; ss[u]=0;
for (int i=head[u];i;i=nxt[i]) {int v=to[i]; if (v==f| |
DEL[V]) continue;
Getroot (V,u);
SIZE[U]+=SIZE[V];
Ss[u]=max (Ss[u],size[v]);
} ss[u]=max (Ss[u],sz-size[u]);
if (Ss[root]>ss[u]) root=u; } int dis (int u,int v) {return Dep[u]+dep[v]-2*dep[lca (u,v)]; void Getdis (int u,int F,int RT) {A[rt].insert (DIS (U,FA[RT)));
for (int i=head[u];i;i=nxt[i]) {int v=to[i]; if (v==f| |
DEL[V]) continue;
Getdis (V,U,RT);
}} void dp (int u,int f) {size[u]=1;
for (int i=head[u];i;i=nxt[i]) {int v=to[i]; if (v==f| |
DEL[V]) continue;
DP (V,U);
SIZE[U]+=SIZE[V];
}} int Build (int x,int f) {getroot (x,f); int u=root; Fa[u]=f;
Getdis (U,f,u); B[u].insert (0);
Del[u]=1;
for (int i=head[u];i;i=nxt[i]) {int v=to[i];
if (Del[v]) continue;
DP (V,U); SZ=SIZE[V];
root=0;
int Srt=build (V,U);
B[u].insert (A[srt].top ());
} if (B[u].size () >1) C.insert (B[u].top () +b[u].sectop ());
return u;
} void Modify (int u,int opt) {if (!opt)//light {if (b[u].size () >1) c.erase (B[u].top () +b[u].sectop ());
B[u].erase (0);
if (B[u].size () >1) C.insert (B[u].top () +b[u].sectop ()); for (int x=u;fa[x];x=fa[x]) {int y=fa[x];
if (B[y].size () >1) c.erase (B[y].top () +b[y].sectop ());
if (A[x].size ()) B[y].erase (A[x].top ());
A[x].erase (DIS (u,y));
if (A[x].size ()) B[y].insert (A[x].top ());
if (B[y].size () >1) C.insert (B[y].top () +b[y].sectop ());
}} else/light out {if (b[u].size () >1) c.erase (B[u].top () +b[u].sectop ());
B[u].insert (0);
if (B[u].size () >1) C.insert (B[u].top () +b[u].sectop ());
for (int x=u;fa[x];x=fa[x]) {int y=fa[x];
if (B[y].size () >1) c.erase (B[y].top () +b[y].sectop ());
if (A[x].size ()) B[y].erase (A[x].top ());
A[x].insert (DIS (u,y));
if (A[x].size ()) B[y].insert (A[x].top ());
if (B[y].size () >1) C.insert (B[y].top () +b[y].sectop ());
}}} int main () {scanf ("%d", &n); for (int i=1;i<n;i++) {int A, B, scanf ("%d%d", &a,&b); Build (A, b);
Build (B,a); } dfs (a);
Cnt=n;
for (int i=1;i<=n;i++) col[i]=1; root=0; ss[0]=n+1;
Sz=n;
int Whatever=build (1,0);
scanf ("%d", &m);
while (m--) {char opt[5]; scanf ("%s", opt);
if (opt[0]== ' G ') {if (cnt<=0) printf (" -1\n");
else if (cnt==1) printf ("%d\n", 0);
else printf ("%d\n", C.top ());
} else {int x; scanf ("%d", &x);
if (Col[x]) {cnt--; modify (x,0); col[x]^=1;}
else{cnt++; modify (x,1); col[x]^=1;}
}} return 0; }