# BZOJ4034：[HAOI2015]树上操作——题解

http://www.lydsy.com/JudgeOnline/problem.php?id=4034

https://www.luogu.org/problemnew/show/P3178

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
typedef long long ll;
const int N=1e5+5;
int X=0,w=0;char ch=0;
while(ch<'0'||ch>'9'){w|=ch=='-';ch=getchar();}
while(ch>='0'&&ch<='9')X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
return w?-X:X;
}
struct node{
int to,nxt;
}edge[2*N];
}
int fa[N],son[N],size[N],val[N],dep[N],idx[N],pos[N],top[N];
ll sum[4*N],lazy[4*N];
void dfs1(int u){
size[u]=1;
int v=edge[i].to;
if(v==fa[u])continue;
fa[v]=u;dep[v]=dep[u]+1;
dfs1(v);
size[u]+=size[v];
if(!son[u]||size[son[u]]<size[v])son[u]=v;
}
}
void dfs2(int u,int anc){
pos[u]=++tot;
idx[tot]=u;
top[u]=anc;
if(!son[u])return;
dfs2(son[u],anc);
int v=edge[i].to;
if(v==fa[u]||v==son[u])continue;
dfs2(v,v);
}
}
void init(){
dep[1]=1;
dfs1(1);
dfs2(1,1);
}
void push(int a,int l,int r){
int mid=(l+r)>>1;
if(lazy[a]){
lazy[a*2]+=lazy[a];
lazy[a*2+1]+=lazy[a];
sum[a*2]+=(mid-l+1)*lazy[a];
sum[a*2+1]+=(r-mid)*lazy[a];
lazy[a]=0;
}
}
void build(int a,int l,int r){
if(l==r){
sum[a]=val[idx[l]];
return;
}
int mid=(l+r)>>1;
build(a*2,l,mid);
build(a*2+1,mid+1,r);
sum[a]=sum[a*2]+sum[a*2+1];
}
ll query(int a,int l,int r,int l1,int r1){
if(r1<l||r<l1)return 0;
if(l1<=l&&r<=r1)return sum[a];
int mid=(l+r)>>1;
push(a,l,r);
return query(a*2,l,mid,l1,r1)+query(a*2+1,mid+1,r,l1,r1);
}
ll pathquery(int x,int y){
ll res=0;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
res+=query(1,1,n,pos[top[x]],pos[x]);
x=fa[top[x]];
}
if(dep[x]>dep[y])swap(x,y);
res+=query(1,1,n,pos[x],pos[y]);
return res;
}
void modify(int a,int l,int r,int l1,int r1,ll p){
if(r1<l||r<l1)return;
if(l1<=l&&r<=r1){
sum[a]+=(r-l+1)*p;
lazy[a]+=p;
return;
}
int mid=(l+r)>>1;
push(a,l,r);
modify(a*2,l,mid,l1,r1,p);
modify(a*2+1,mid+1,r,l1,r1,p);
sum[a]=sum[a*2]+sum[a*2+1];
}
int main(){
for(int i=1;i<n;i++){
}
init();
build(1,1,n);
while(q--){
if(op==1){
modify(1,1,n,pos[x],pos[x],a);
}
if(op==2){
modify(1,1,n,pos[x],pos[x]+size[x]-1,a);
}
if(op==3){
printf("%lld\n",pathquery(x,1));
}
}
return 0;
}

+++++++++++++++++++++++++++++++++++++++++++

+本文作者：luyouqi233。 　　　　　　　　　　　　　　+

+欢迎访问我的博客：http://www.cnblogs.com/luyouqi233/+

+++++++++++++++++++++++++++++++++++++++++++

posted @ 2018-03-12 15:56  luyouqi233  阅读(119)  评论(0编辑  收藏  举报