2
19
2016
0

[BZOJ2836] 魔法树

因为一棵树的子树一定在dfs序上是连续的

所以直接修改就行了

#include<cstdio>
#include<algorithm>
using namespace std;

struct Edge{
int b,next;
}e[1000005];

struct SegTree{
int l,r;
long long tag,sum;
}tree[1000005];

int n,q,en,cnt,top[400005],id[400005],pre[400005],dep[400005],son[400005],h[400005],siz[400005],fa[400005];

void AddEdge(int sa,int sb){
e[++en].b=sb;
e[en].next=h[sa];
h[sa]=en;
}

void Pushdown(int root){
if(tree[root].tag){
	tree[root*2].tag+=tree[root].tag;
	tree[root*2].sum+=tree[root].tag*(tree[root*2].r-tree[root*2].l+1);
	tree[root*2+1].tag+=tree[root].tag;
	tree[root*2+1].sum+=tree[root].tag*(tree[root*2+1].r-tree[root*2+1].l+1);
	tree[root].tag=0;
}
}

void Pushup(int root){
tree[root].sum=tree[root*2].sum+tree[root*2+1].sum;
}

void Build(int root,int l,int r){
tree[root].l=l;
tree[root].r=r;
if(l==r){
    tree[root].sum=0;
    return;
}
int mid=(l+r)/2;
Build(root*2,l,mid);
Build(root*2+1,mid+1,r);
tree[root].sum=tree[root*2].sum+tree[root*2+1].sum;
}

void Add(int root,int l,int r,long long v){
if(tree[root].l>=l && tree[root].r<=r){
	tree[root].tag+=v;
	tree[root].sum+=v*(tree[root].r-tree[root].l+1);
	return;
}
Pushdown(root);
int mid=tree[root].l+tree[root].r>>1;
if(l<=mid)Add(root*2,l,r,v);
if(r>mid)Add(root*2+1,l,r,v);
Pushup(root);
}

long long Sum(int root,int l,int r){
if(tree[root].l>=l && tree[root].r<=r){
	return tree[root].sum;
}
Pushdown(root);
int mid=tree[root].l+tree[root].r>>1;
long long ans=0;
if(l<=mid)ans+=Sum(root*2,l,r);
if(r>mid)ans+=Sum(root*2+1,l,r);
return ans;
}

void dfs1(int u,int father,int deep){
fa[u]=father;
dep[u]=deep;
siz[u]=1;
son[u]=0;
for(int i=h[u];i;i=e[i].next){
    int v=e[i].b;
    if(v==father)continue;
    dfs1(v,u,deep+1);
    siz[u]+=siz[v];
    if(siz[v]>siz[son[u]]){
        son[u]=v;
    }
}
}
 
void dfs2(int u,int ux){
top[u]=ux;
id[u]=++cnt;
pre[cnt]=u;
if(son[u])dfs2(son[u],ux);
else return;
for(int i=h[u];i;i=e[i].next){
    int v=e[i].b;
    if(v!=son[u] && v!=fa[u]){dfs2(v,v);}
}
}

void AddLine(int u,int v,long long val){
int f1=top[u],f2=top[v];
while(f1!=f2){
	if(dep[f1]<dep[f2]){swap(u,v);swap(f1,f2);}
	Add(1,id[f1],id[u],val);
	u=fa[f1];
	f1=top[u];
}
if(dep[u]>dep[v])swap(u,v);
//printf("%d %d\n",id[u],id[v]);
Add(1,id[u],id[v],val);
}

int main(){
freopen("2836.in","r",stdin);
freopen("2836.out","w",stdout);
scanf("%d",&n);
for(int i=1;i<n;i++){
	int u,v;
	scanf("%d %d",&u,&v);
	AddEdge(u+1,v+1);
	AddEdge(v+1,u+1);
}
Build(1,1,n);
dfs1(1,0,1);
dfs2(1,1);
scanf("%d",&q);
while(q--){
	int u,v;
	long long val;
	char s[3];
	scanf("%s",s);
	if(s[0]=='A'){
		scanf("%d %d %lld",&u,&v,&val);
		AddLine(u+1,v+1,val);
	}
	if(s[0]=='Q'){
		scanf("%d",&u);
		//printf("IS:%d %d %d\n",id[u+1],siz[u+1],u+1);
		printf("%lld\n",Sum(1,id[u+1],id[u+1]+siz[u+1]-1));
	}
}
return 0;
}
Category: BZOJ | Tags: OI bzoj | Read Count: 507

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter

Host by is-Programmer.com | Power by Chito 1.3.3 beta | Theme: Aeros 2.0 by TheBuckmaker.com