BZOJ - 3730 Shock (+ dendritic tree dotted array)

Two modes of operation:

1. query node tree node x is no more than the weighted sum of k and

2. The node weights x, y modify

Dotted tree template title.

First consider a more violent approach: with dp thought of tree, the tree will be converted into a rooted tree, provided F [u] [k] is a node u and its sub-tree is no more than k and the right point, then ans (x, k) = f [u] [k] + f [fa [u]] [k-1] -f [u] [k-2] + f [fa [fa [u]]] [k -2] -f [fa [u]] [k-3] ..., but if it is too high GG tree, and if the tree can become high enough level logn.

Establishing dotted tree (tree points formed during partition), each tree node maintains two arrays, on a weight to maintain the center of gravity of each node and the distance, a maintenance imaginary father (point partial tree father) and the weights (for receiving repellent) on each distance in "the node direction". Also maintain a separate data structure is used to find the distance between two points of the original tree (tree sectional relatively high efficiency), and to modify the current node asking it began to jump up. (Dotted tree is a tree logn high level of violence can jump up)

 Overall complexity $ (nlogn + qlog ^ 2n) O $

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 typedef long long ll;
  4 const int N=1e5+10,inf=0x3f3f3f3f;
  5 struct E {int v,nxt;} e[N<<1];
  6 int a[N],hd[N],ne,n,Q,siz[N],mx[N],vis[N],RT,tot,cnt[N],fa[N];
  7 int buf[N*40],*ptr=buf;
  8 struct BIT {
  9     int *c,n;
 10     int lb(int x) {return x&-x;}
 11     void add(int u,int x) {for(; u<=n; u+=lb(u))c[u]+=x;}
 12     int get(int u) {int ret=0; for(u=min(u,n); u; u-=lb(u))ret+=c[u]; return ret;}
 13     void build(int* a) {
 14         for(int i=1; i<=n; ++i)c[i]=a[i];
 15         for(int i=1; i<=n; ++i)if(i+lb(i)<=n)c[i+lb(i)]+=c[i];
 16     }
 17 } c[N][2];
 18 BIT newBIT(int n) {BIT t= {ptr,n}; ptr+=n+1; return t;}
 19 struct LCA {
 20     int fa[N],son[N],dep[N],siz[N],top[N];
 21     void dfs1(int u,int f,int d) {
 22         fa[u]=f,son[u]=0,dep[u]=d,siz[u]=1;
 23         for(int i=hd[u]; ~i; i=e[i].nxt) {
 24             int v=e[i].v;
 25             if(v==fa[u])continue;
 26             dfs1(v,u,d+1),siz[u]+=siz[v];
 27             if(siz[v]>siz[son[u]])son[u]=v;
 28         }
 29     }
 30     void dfs2(int u,int tp) {
 31         top[u]=tp;
 32         if(son[u])dfs2(son[u],tp);
 33         for(int i=hd[u]; ~i; i=e[i].nxt) {
 34             int v=e[i].v;
 35             if(v==fa[u]||v==son[u])continue;
 36             dfs2(v,v);
 37         }
 38     }
 39     int lca(int u,int v) {
 40         for(; top[u]!=top[v]; u=fa[top[u]])if(dep[top[u]]<dep[top[v]])swap(u,v);
 41         return dep[u]<dep[v]?u:v;
 42     }
 43     int dis(int u,int v) {return dep[u]+dep[v]-2*dep[lca(u,v)];}
 44 } lca;
 45 void link(int u,int v) {e[ne]= (E) {v,hd[u]},hd[u]=ne++;}
 46 void getrt(int u,int f) {
 47     siz[u]=1,mx[u]=0;
 48     for(int i=hd[u]; ~i; i=e[i].nxt) {
 49         int v=e[i].v;
 50         if(vis[v]||v==f)continue;
 51         getrt(v,u),siz[u]+=siz[v],mx[u]=max(mx[u],siz[v]);
 52     }
 53     mx[u]=max(mx[u],tot-siz[u]);
 54     if(mx[u]<mx[RT])RT=u;
 55 }
 56 void getdis(int u,int f,int d) {
 57     cnt[d]+=a[u];
 58     for(int i=hd[u]; ~i; i=e[i].nxt) {
 59         int v=e[i].v;
 60         if(vis[v]||v==f)continue;
 61         getdis(v,u,d+1);
 62     }
 63 }
 64 void cal(int u,int f) {
 65     int m=1;
 66     for(; cnt[m]; ++m);
 67     --m;
 68     c[u][f]=newBIT(m);
 69     c[u][f].build(cnt);
 70     for(int i=1; i<=m; ++i)cnt[i]=0;
 71 }
 72 void solve(int u) {
 73     getdis(u,0,1),cal(u,0),vis[u]=1;
 74     for(int i=hd[u]; ~i; i=e[i].nxt) {
 75         int v=e[i].v;
 76         if(vis[v])continue;
 77         getdis(v,0,1),RT=0,tot=siz[v];
 78         getrt(v,0),cal(RT,1),fa[RT]=u,solve(RT);
 79     }
 80 }
 81 void upd(int u,int x) {
 82     x-=a[u],a[u]+=x;
 83     int dis=0;
 84     c[u][0].add(dis+1,x);
 85     for(int v=u; fa[v]; v=fa[v]) {
 86         dis=lca.dis(u,fa[v]);
 87         c[fa[v]][0].add(dis+1,x),c[v][1].add(dis,x);
 88     }
 89 }
 90 int qry(int u,int d) {
 91     int ret=0,dis=d;
 92     ret+=c[u][0].get(dis+1);
 93     for(int v=u; fa[v]; v=fa[v]) {
 94         dis=d-lca.dis(u,fa[v]);
 95         if(dis>=0)ret+=c[fa[v]][0].get(dis+1)-c[v][1].get(dis);
 96     }
 97     return ret;
 98 }
 99 int main() {
100     memset(hd,-1,sizeof hd),ne=0;
101     scanf("%d%d",&n,&Q);
102     for(int i=1; i<=n; ++i)scanf("%d",&a[i]);
103     for(int i=1; i<n; ++i) {
104         int u,v;
105         scanf("%d%d",&u,&v);
106         link(u,v);
107         link(v,u);
108     }
109     mx[0]=inf,RT=0,tot=n,getrt(1,0),fa[RT]=0,solve(RT);
110     lca.dfs1(1,0,1),lca.dfs2(1,1);
111     for(int la=0; Q--;) {
112         int f,u,x;
113         scanf("%d%d%d",&f,&u,&x);
114         u^=la,x^=la;
115         if(f==0)printf("%d\n",la=qry(u,x));
116         else upd(u,x);
117     }
118     return 0;
119 }

 

Guess you like

Origin www.cnblogs.com/asdfsag/p/12513986.html
Recommended