Topic: Given a tree, starting at each point is a black spot, changing the state of a point several times or asking the distance from the two black dots farthest away
"Cherish life away from STL, but I still use the STL series shamefully"
Legend of the dynamic tree Division ... It's not really that divine.
↑ Don't listen to this fool. This is the STL card one day Qaq
We've connected the center of gravity that we've traversed during the division, and the center of gravity on the next layer of gravity links to a new tree.
Now let's start talking about this new tree.
Obviously the height of this tree will not exceed O (Logn)
Then we open two heaps per node.
The first heap records the distance from all nodes in the subtree to the Father node
The second heap records the heap top of all child nodes
Then the maximum and minor in the heap 2 of a node is the longest chain that passes through the node in the subtree.
Then we end up with a global heap that records the sum of the maximum and sub-large values in all heap 2
So the top of the heap is the answer.
Modify what you yy it is good for physical and mental health Qaq Qaq Qaq
This memory card's flying up AH--
#include <queue> #include <cstdio> #include <cstring> #include <iostream> #include < Algorithm> #define M 100100using namespace Std;struct priority_queue{priority_queue<int> heap,delmark;void Insert (int x) {heap.push (x);} void Erase (int x) {delmark.push (x);} void Pop () {while (Delmark.size () && heap.top () ==delmark.top ()) Heap.pop (), Delmark.pop (); Heap.pop ();} int Top () {while (Delmark.size () && heap.top () ==delmark.top ()) Heap.pop (), Delmark.pop (); return Heap.top ();} int second_top () {int temp=top (); Pop (); int re=top (); Insert (temp); return re;} int Size () {return heap.size ()-delmark.size ();}} S1[m],s2[m],ans;struct abcd{int to,next;bool Ban;} Table[m<<1];int head[m],tot=1;int n,m,cnt;int fa[m];bool status[m];int log_2[m<<1],dpt[m],pos[m],a[m <<1][20],t;void Add (int x,int y) {table[++tot].to=y;table[tot].next=head[x];head[x]=tot;} int get_size (int x,int from) {int i,re=1;for (i=head[x];i;i=table[i].next) {if (table[i].ban| | Table[i].to==from) ContinuE;re+=get_size (table[i].to,x);} return re;} int get_centre_of_gravity (int x,int from,int size,int &cg) {int i,re=1,flag=true;for (i=head[x];i;i=table[i].next) {if (table[i].ban| | Table[i].to==from) Continue;int temp=get_centre_of_gravity (TABLE[I].TO,X,SIZE,CG); if (temp<<1>size) flag= False;re+=temp;} if (size-re<<1>size) flag=false;if (flag) Cg=x;return re;} void DFS (int x,int from,int dpt,priority_queue &s) {int I;s.insert (DPT); for (I=head[x];i;i=table[i].next) {if (table [i].ban| | Table[i].to==from) Continue;dfs (table[i].to,x,dpt+1,s);}} void Insert (Priority_queue &s) {if (S.size () >=2) {int temp=s.top () +s.second_top (); ans. Insert (temp);}} void Erase (Priority_queue &s) {if (S.size () >=2) {int temp=s.top () +s.second_top (); ans. Erase (temp);}} int tree_divide_and_conquer (int x) {int i,size,cg;size=get_size (x,0); Get_centre_of_gravity (X,0,SIZE,CG); S2[CG]. Insert (0); for (I=head[cg];i;i=table[i].next) if (!table[i].ban) {table[i].ban=table[i^1].ban=true; Priority_queue S;dfs (table[i].to,0,1,s);int Temp=tree_divide_and_conquer (table[i].to); FA[TEMP]=CG;S1[TEMP]=S;S2[CG]. Insert (S1[temp]. Top ());} Insert (S2[CG]); return CG;} void DFS (int x,int from) {int i;a[pos[x]=++t][0]=dpt[x]=dpt[from]+1;for (i=head[x];i;i=table[i].next) if (table[i].to! =from) {DFS (table[i].to,x); a[++t][0]=dpt[x];}} int lca_depth (int x,int y) {x=pos[x];y=pos[y];if (x>y) swap (x, y), int l=log_2[y-x+1];return min (a[x][l],a[y-(1< <l) +1][l]);} int Distance (int x,int y) {return dpt[x]+dpt[y]-2*lca_depth (x, y);} void turn_on (int x) {int i; Erase (S2[x]); S2[x]. Insert (0), insert (S2[x]), for (I=x;fa[i];i=fa[i]) {Erase (S2[fa[i]), if (S1[i]. Size ()) S2[fa[i]]. Erase (S1[i]. Top ()); S1[i]. Insert (Distance (fa[i],x)); if (S1[i]. Size ()) S2[fa[i]]. Insert (S1[i]. Top ()); Insert (S2[fa[i]);}} void Turn_off (int x) {int i; Erase (S2[x]); S2[x]. Erase (0), Insert (S2[x]), for (I=x;fa[i];i=fa[i]) {Erase (S2[fa[i]]), if (S1[i]. Size ()) S2[fa[i]]. Erase (S1[i]. Top ()); S1[i]. Erase (Distance (fa[i],x)), if (S1[i]. Size ()) S2[fa[i]]. Insert (S1[i]. Top ()); Insert (S2[fa[i]);}} int main () {int i,j, X,y;char p[10];cin>>n;cnt=n;for (i=1;i<n;i++) {scanf ("%d%d", &x,&y); ADD (x, y); ADD (y,x);} Tree_divide_and_conquer (1);D FS (1,0), for (i=2;i<=t;i++) log_2[i]=log_2[i>>1]+1;for (j=1;j<=log_2[t];j+ +) for (i=1;i+ (1<<j) -1<=t;i++) a[i][j]=min (a[i][j-1],a[i+ (1<<j-1)][j-1]); for (i=1;i<=n;i++) Status[i]=true;cin>>m;for (i=1;i<=m;i++) {scanf ("%s", p), if (p[0]== ' G ') {if (cnt<=1) printf ("%d\n", cnt-1) ; elseprintf ("%d\n", ans. Top ());} ELSE{SCANF ("%d", &x); if (status[x]==true) {--cnt;status[x]=false; Turn_off (x);} Else{++cnt;status[x]=true; TURN_ON (x);}}} return 0;}
Bzoj 1095 ZJOI2007 Hide Hide and seek dynamic tree partition + heap