bzoj3924 [Zjoi2015]幻想乡战略游戏(动态点分治)
2018-02-23 21:45
435 查看
就是求带权重心,可以修改点权。
我们首先建出重心树。对于每个节点x记
s1[x]–x的子树到x的答案,
s2[x]–x的子树的点权和,
s3[x]–x的子树到fa[x]的答案。
那我们就可以通过这些信息得出以x为重心的答案(在重心树上一直往上跳,复杂度O(log n).)
修改点权时,最多影响logn个点,我们就O(logn)的更新一下这些点的信息。
怎么找带权重心呢?从重心树的根开始,枚举它的所有出边(原树中的边),如果往那个方向走得到的答案更优,就走到那个方向的重心树中的儿子上去,否则最优的就是当前点了。(可以证明最多只有一个方向比我目前的点优,如果一个方向紧邻我的点的答案比我大,则这个方向的所有点的答案都肯定比我大。)
复杂度O(nlog2n∗20)O(nlog2n∗20)
我们首先建出重心树。对于每个节点x记
s1[x]–x的子树到x的答案,
s2[x]–x的子树的点权和,
s3[x]–x的子树到fa[x]的答案。
那我们就可以通过这些信息得出以x为重心的答案(在重心树上一直往上跳,复杂度O(log n).)
修改点权时,最多影响logn个点,我们就O(logn)的更新一下这些点的信息。
怎么找带权重心呢?从重心树的根开始,枚举它的所有出边(原树中的边),如果往那个方向走得到的答案更优,就走到那个方向的重心树中的儿子上去,否则最优的就是当前点了。(可以证明最多只有一个方向比我目前的点优,如果一个方向紧邻我的点的答案比我大,则这个方向的所有点的答案都肯定比我大。)
复杂度O(nlog2n∗20)O(nlog2n∗20)
#include <cstdio> #include <cstring> #include <algorithm> #include <queue> using namespace std; #define ll long long #define inf 0x3f3f3f3f #define N 100010 inline char gc(){ static char buf[1<<16],*S,*T; if(S==T){T=(S=buf)+fread(buf,1,1<<16,stdin);if(T==S) return EOF;} return *S++; } inline int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar(); return x*f; } int n,m,fa ,sz ,f ,sumsz,rt,h ,num=0,root,dis ; int dep ,mn[N<<1][20],dfn ,dfnum=0,Log[N<<1]; ll s1 ,s2 ,s3 ;//s1[x]--x的子树到x的答案,s2[x]--x的子树的点权和,s3[x]--x的子树到fa[x]的答案 struct edge{ int to,next,val; }data[N<<1]; bool vis ; vector<int>son ,Gson ; inline void dfs(int x,int Fa){ mn[++dfnum][0]=x;dfn[x]=dfnum; for(int i=h[x];i;i=data[i].next){ int y=data[i].to;if(y==Fa) continue; dep[y]=dep[x]+1;dis[y]=dis[x]+data[i].val; dfs(y,x);mn[++dfnum][0]=x; } } inline void inirmq(){ Log[0]=-1; for(int i=1;i<=n<<1;++i) Log[i]=Log[i>>1]+1; for(int i=1;i<=Log[n<<1];++i) for(int j=1;j<=2*n-1;++j){ if(j+(1<<i-1)>2*n-1) break; mn[j][i]=dep[mn[j][i-1]]<dep[mn[j+(1<<i-1)][i-1]]?mn[j][i-1]:mn[j+(1<<i-1)][i-1]; } } inline void dfs1(int x,int Fa){ sz[x]=1; for(int i=h[x];i;i=data[i].next){ int y=data[i].to;if(vis[y]||y==Fa) continue; dfs1(y,x);sz[x]+=sz[y]; } } inline void dfs2(int x,int Fa){ f[x]=0; for(int i=h[x];i;i=data[i].next){ int y=data[i].to;if(vis[y]||y==Fa) continue; dfs2(y,x);f[x]=max(f[x],sz[y]); }f[x]=max(f[x],sumsz-sz[x]);if(f[x]<f[rt]) rt=x; } inline void getG(int x){ vis[x]=1;dfs1(x,0); for(int i=h[x];i;i=data[i].next){ int y=data[i].to;if(vis[y]) continue; sumsz=sz[y];rt=0;dfs2(y,0);fa[rt]=x; son[x].push_back(y);Gson[x].push_back(rt);getG(rt); } } inline int lca(int x,int y){ x=dfn[x],y=dfn[y];if(x>y) swap(x,y); int t=Log[y-x+1]; return dep[mn[x][t]]<dep[mn[y-(1<<t)+1][t]]?mn[x][t]:mn[y-(1<<t)+1][t]; } inline int caldis(int x,int y){ return dis[x]+dis[y]-2*dis[lca(x,y)]; } inline void change(int x,int val){ for(int i=x;i;i=fa[i]){ s1[i]+=(ll)caldis(i,x)*val; s2[i]+=val; if(fa[i]) s3[i]+=(ll)caldis(x,fa[i])*val; } } inline ll calc(int x){ ll res=s1[x]; for(int i=x;fa[i];i=fa[i]){ res+=s1[fa[i]]-s3[i]+(s2[fa[i]]-s2[i])*caldis(x,fa[i]); }return res; } inline ll ask(int x){ ll res=calc(x); for(int i=0;i<son[x].size();++i){ int y=son[x][i]; if(calc(y)<res) return ask(Gson[x][i]); }return res; } int main(){ // freopen("a.in","r",stdin); n=read();m=read();f[0]=inf; for(int i=1;i<n;++i){ int x=read(),y=read(),val=read(); data[++num].to=y;data[num].next=h[x];h[x]=num;data[num].val=val; data[++num].to=x;data[num].next=h[y];h[y]=num;data[num].val=val; }dfs(1,0);inirmq(); dfs1(1,0);sumsz=n;rt=0;dfs2(1,0);fa[rt]=0;root=rt;getG(rt); while(m--){ int x=read(),val=read(); change(x,val);printf("%lld\n",ask(root)); }return 0; }
相关文章推荐
- BZOJ 3924: [Zjoi2015]幻想乡战略游戏(动态点分治)
- [ZJOI2015][bzoj3924] 幻想乡战略游戏 [动态点分治]
- 【bzoj3924】[Zjoi2015]幻想乡战略游戏 动态点分治
- [BZOJ3924][ZJOI2015]幻想乡战略游戏(动态点分治)
- [BZOJ3924][Zjoi2015]幻想乡战略游戏(动态点分治)
- BZOJ 3924: [Zjoi2015]幻想乡战略游戏(动态点分治)
- 【BZOJ3924】【Zjoi2015】幻想乡战略游戏(树链剖分+点分治)
- BZOJ.3924.[ZJOI2015]幻想乡战略游戏(动态点分治)
- [BZOJ]3924 [ZJOI2015] 幻想乡战略游戏 树链剖分
- bzoj 3924: [Zjoi2015]幻想乡战略游戏
- 【BZOJ3924】幻想乡战略游戏(动态点分治)
- BZOJ 3924: [Zjoi2015]幻想乡战略游戏 动态树分治
- 【BZOJ3924】幻想乡战略游戏(动态点分治)
- 【ZJOI 2015 幻想乡战略游戏】【动态点分治】
- 洛谷P3345 [ZJOI2015]幻想乡战略游戏(动态点分治,树的重心,二分查找,Tarjan-LCA,树上差分)
- BZOJ 3924 Zjoi2015 幻想乡战略游戏 动态树分治
- [BZOJ3924][ZJOI2015]幻想乡战略游戏-动态树分治
- [BZOJ3924][Zjoi2015][点分树][暴力]幻想乡战略游戏
- 【BZOJ3924】[Zjoi2015]幻想乡战略游戏 动态树分治
- bzoj 3924: [Zjoi2015]幻想乡战略游戏