2019icpc Shanghai A network game dynamic segment tree maintenance and tree diameter end

Topic links: https://nanti.jisuanke.com/t/41398

Teammate's blog: https://blog.csdn.net/weixin_44059127/article/details/100941413

The meaning of problems: there is given an edge weight of the tree of n nodes, the given operation m times, ①: C, ei, wi, modification right edge strips ei is wi; ②: Q, vi, vi inquiry to other points the longest distance. (N, m <= 1e5)

First, we can know that for static tree we can find the diameter of its endpoints twice dfs.

Then from a point farthest point must be the diameter of the end, this is not to say. . .

So the question becomes support modification right side, the maintenance of the tree diameter and endpoints, as well as seeking distance between two points.

The latter can thus see: Kazuki chain split as DFS start and again, so that we can know its subtree of a node, then dis [u] = X + u corresponds to the subtree are dis + = x. So dis nodes can be added to the differential Fenwick tree maintenance, so that you can modify with a dis. Then the distance between two points is directly lca ran out.

For the former, we can see: dfs time, if node u dfs, dfs (V, u) after the sequence is in dfs into account in a u (see specific code) so now dfs sequence u u becomes subtree v1. . . . u v2. . . . . u. . . . .

Two equal distance dis [v1] + dis [v2] - 2 * dis [lca (v1, v2)], where lca (v1, v2) is u. Therefore, the minimum segment tree maintenance interval (i.e. LCA, as a u put between v1 and V2), then the two sections is the longest distance on the order dfs, a division sides u, u of the maximum left ( dis [v1]) + u right of the maximum (dis [v2]) - minimum interval (dis [u]).

So how to ensure that the division u do? We can maintain a tree line interval maximum value (mx), and the maximum value of -2 * mi maximum range on the right (lmx) as well as the maximum value of the left - 2 * maximum range mi (rmx), then the interval two most the combined long-distance range that is left and right son lmx + mx son and son left and right son rmx + mx. While maintaining the look lmx, mx, rmx endpoint thousand million.

Also, the variable name represents the tree line labeled 1, 2 Fenwick tree.

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 typedef long long ll;
  4 #define inf 0x3f3f3f3f
  5 #define pq priority_queue<int,vector<int>,greater<int> >
  6 const int N=2e5+9;
  7 struct edge{
  8     int to,nex;
  9     ll w;
 10 }e[N<<1];
 11 struct node{
 12     ll mx,mi,lmx,rmx,val,lazy;
 13     int idl,idr,idmx;
 14     int u,v;
 15 }tr[N<<2];
 16 int h[N],f[N][25],dep[N],st2[N],ed2[N];
 17 ll tr2[N],dis[N];
 18 int rnk[N<<3],st1[N<<3],ed1[N<<3];
 19 int cnt=1,n,m,tot1=0,tot2=0;
 20 void add(int u,int v,ll wi){
 21     e[++cnt]=(edge){v,h[u],wi};
 22     h[u]=cnt;
 23 }
 24 void dfs(int u,int fa){
 25     st1[u]=++tot1; st2[u]=++tot2; rnk[tot1]=u;
 26     f[u][0]=fa; dep[u]=dep[fa]+1;
 27     for(int i=1;i<=20;++i) f[u][i]=f[ f[u][i-1] ][i-1];
 28     for(int i=h[u];i;i=e[i].nex){
 29         int v=e[i].to;
 30         if(v==fa) continue;
 31         dis[v]=dis[u]+e[i].w;
 32         dfs(v,u);
 33         rnk[++tot1]=u;
 34     }
 35     ed1[u]=tot1; ed2[u]=tot2;
 36 }
 37 void push_up(int o){
 38     tr[o].mx=max(tr[o<<1].mx,tr[o<<1|1].mx);
 39     tr[o].mi=min(tr[o<<1].mi,tr[o<<1|1].mi);
 40     tr[o].lmx=max( max(tr[o<<1].lmx,tr[o<<1|1].lmx) , tr[o<<1].mx-2*tr[o<<1|1].mi);
 41     tr[o].rmx=max( max(tr[o<<1].rmx,tr[o<<1|1].rmx) , tr[o<<1|1].mx-2*tr[o<<1].mi);
 42     tr[o].val=max( max(tr[o<<1].val,tr[o<<1|1].val), max(tr[o<<1].lmx+tr[o<<1|1].mx,tr[o<<1].mx+tr[o<<1|1].rmx) );
 43 
44      if (p [o] .lmx == p [o << 1 ] .lmx) p [o] .idl = p [o << 1 ] .idl;
45      else  if (p [o] .lmx == p [o << 1 | 1 ] .lmx) p [o] .idl = p [o << 1 | 1 ] .idl;
46      else p [o] .idl = p [o << 1 ] .idmx;
47  
48      if (p [o] .rmx == p [o << 1 ] .rmx) p [o] .idr = p [o << 1 ] .idr;
49      else  if (p [o] .rmx == p [o << 1 | 1 ] .rmx) p [o] .idr = p [o << 1 | 1 ] .idr;
50     else tr[o].idr=tr[o<<1|1].idmx;
 51 
 52     if(tr[o].mx==tr[o<<1].mx) tr[o].idmx=tr[o<<1].idmx;
 53     else tr[o].idmx=tr[o<<1|1].idmx;
 54 
 55     if(tr[o].val==tr[o<<1].val) tr[o].u=tr[o<<1].u,tr[o].v=tr[o<<1].v;
 56     else if(tr[o].val==tr[o<<1|1].val) tr[o].u=tr[o<<1|1].u,tr[o].v=tr[o<<1|1].v;
 57     else if(tr[o].val==tr[o<<1].lmx+tr[o<<1|1].mx) tr[o].u=tr[o<<1].idl,tr[o].v=tr[o<<1|1].idmx;
 58     else tr[o].u=tr[o<<1].idmx,tr[o].v=tr[o<<1|1].idr;
 59 }
 60 void push_down(int o){
 61     if(tr[o].lazy){
 62         ll tem=tr[o].lazy; tr[o].lazy=0;
 63         tr[o<<1].lazy+=tem; tr[o<<1|1].lazy+=tem;
 64         tr[o<<1].mx+=tem; tr[o<<1].mi+=tem; tr[o<<1].lmx-=tem; tr[o<<1].rmx-=tem;
 65         tr[o<<1|1].mx+=tem; tr[o<<1|1].mi+=tem; tr[o<<1|1].lmx-=tem; tr[o<<1|1].rmx-=tem;
 66     }
 67 }
 68 void build(int o,int l,int r){
 69     tr[o].lazy=0;
 70     if(l==r){
 71         tr[o].idl=tr[o].idr=tr[o].idmx=rnk[l];
 72         ll d=dis[rnk[l]];
 73         tr[o].mx=tr[o].mi=d;
 74         tr[o].lmx=tr[o].rmx=-d;
 75         tr[o].val=0;
 76         tr[o].u=tr[o].v=rnk[l];
 77         return;
 78     }
 79     int m=(l+r)>>1;
 80     build(o<<1,l,m);
 81     build(o<<1|1,m+1,r);
 82     push_up(o);
 83 }
 84 void change(int o,int l,int r,int x,int y,ll w){
 85     if(x<=l && r<=y){
 86         tr[o].lazy+=w; tr[o].mx+=w; tr[o].mi+=w;
 87         tr[o].lmx-=w; tr[o].rmx-=w;
 88         return;
 89     }
 90     push_down(o);
 91     int m=(l+r)>>1;
 92     if(x<=m) change(o<<1,l,m,x,y,w);
 93     if(y>m)  change(o<<1|1,m+1,r,x,y,w);
 94     push_up(o);
 95 }
 96 
 97 void add2(int x,ll v){ for(;x<=n;x+=x&(-x)) tr2[x]+=v; }
 98 ll sum2(int x){
 99     ll res=0;
100     for(;x;x-=x&(-x)) res+=tr2[x];
101     return res;
102 }
103 
104 int lca(int u,int v){
105     if(dep[u]<dep[v]) swap(u,v);
106     for(int i=20;i>=0;--i){
107         if(dep[f[u][i]] >= dep[v]) u=f[u][i];
108     }
109     if(u==v) return u;
110     for(int i=20;i>=0;--i){
111         if(f[u][i]!=f[v][i]) u=f[u][i],v=f[v][i];
112     }
113     return f[u][0];
114 }
115 ll cal(int u,int v){
116     int fa=lca(u,v);
117     ll du=sum2(st2[u]),dv=sum2(st2[v]),dfa=sum2(st2[fa]);
118     return du+dv-2*dfa;
119 }
120 
121 int main(){
122     scanf("%d",&n);
123     for(int i=1;i<n;++i){
124         int u,v; ll w; scanf("%d %d %lld",&u,&v,&w);
125         add(u,v,w); add(v,u,w);
126     }
127     dfs(1,0);
128     for(int i=1;i<=n;++i){ add2(st2[i],dis[i]); add2(st2[i]+1,-dis[i]); }
129     build(1,1,tot1);
130     scanf("%d",&m);
131     char s[3];
132     for(int i=1;i<=m;++i){
133         scanf("%s",s);
134         if(s[0]=='Q'){
135             int x; scanf("%d",&x);
136             int u=tr[1].u,v=tr[1].v;
137             printf("%lld\n",max(cal(u,x),cal(v,x)));
138         }
139         else{
140             int x;ll y; scanf("%d %lld",&x,&y);
141             x*=2;
142             int u=e[x].to,v=e[x|1].to;
143             u= dep[u]>dep[v] ? u : v ;
144             change(1,1,tot1,st1[u],ed1[u],y-e[x].w);
145             add2(st2[u],y-e[x].w); add2(ed2[u]+1,e[x].w-y);
146             e[x].w=e[x|1].w=y;
147         }
148     }
149     return 0;
150 }
View Code

 

Guess you like

Origin www.cnblogs.com/xiaobuxie/p/11545964.html