您的位置:首页 > 其它

bzoj 2836: 魔法树(树链剖分)

2016-05-11 19:22 531 查看

2836: 魔法树

Time Limit: 10 Sec Memory Limit: 128 MB

Submit: 247 Solved: 96

[Submit][Status][Discuss]

Description



Input



Output



Sample Input

4

0 1

1 2

2 3

4

Add 1 3 1

Query 0

Query 1

Query 2

Sample Output

3

3

2

HINT

Source



[Submit][Status][Discuss]

题解:dfs序+树链剖分

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define N 200003
#define LL long long
using namespace std;
int n,m,t,tot,sz;
LL tr[N*4],delta[N*4];
int point
,next
,v
,belong
,size
,son
,fa
,deep
;
int pos
,l
,r
;
void add(int x,int y)
{
tot++; next[tot]=point[x]; point[x]=tot; v[tot]=y;
tot++; next[tot]=point[y]; point[y]=tot; v[tot]=x;
}
void dfs(int x,int f)
{
size[x]=1;
for (int i=point[x];i;i=next[i])
if (v[i]!=f)
{
deep[v[i]]=deep[x]+1;
dfs(v[i],x);
fa[v[i]]=x;
size[x]+=size[v[i]];
if (size[v[i]]>size[son[x]])
son[x]=v[i];
}
}
void build(int k,int chain)
{
belong[k]=chain; pos[k]=++sz;
l[k]=sz; r[k]=sz;
if (!son[k]) return;
build(son[k],chain);
for (int i=point[k];i;i=next[i])
if (v[i]!=fa[k]&&v[i]!=son[k])
build(v[i],v[i]);
r[k]=sz;
}
void pushdown(int now,int l,int r)
{
if (!delta[now]) return;
delta[now<<1]+=delta[now];
delta[now<<1|1]+=delta[now];
int mid=(l+r)/2;
tr[now<<1]+=(LL)(mid-l+1)*delta[now];
tr[now<<1|1]+=(LL)(r-mid)*delta[now];
delta[now]=0;
}
LL query(int now,int l,int r,int ll,int rr)
{
if (l>=ll&&r<=rr) return tr[now];
pushdown(now,l,r);
int mid=(l+r)/2;
LL ans=0;
if (ll<=mid)  ans+=query(now<<1,l,mid,ll,rr);
if (rr>mid)  ans+=query(now<<1|1,mid+1,r,ll,rr);
return ans;
}
void change(int now,int l,int r,int ll,int rr,LL v)
{
if (l>=ll&&r<=rr){
tr[now]+=(LL)v*(r-l+1);
delta[now]+=v;
return;
}
pushdown(now,l,r);
int mid=(l+r)/2;
if (ll<=mid) change(now<<1,l,mid,ll,rr,v);
if (rr>mid) change(now<<1|1,mid+1,r,ll,rr,v);
tr[now]=tr[now<<1]+tr[now<<1|1];
}
void solve(int x,int y,LL v)
{
while (belong[x]!=belong[y])
{
if (deep[belong[x]]<deep[belong[y]]) swap(x,y);
change(1,1,n,pos[belong[x]],pos[x],v);
x=fa[belong[x]];
}
if (deep[x]>deep[y]) swap(x,y);
change(1,1,n,pos[x],pos[y],v);
}
int main()
{
freopen("a.in","r",stdin);
scanf("%d",&n);
for (int i=1;i<n;i++)
{
int x,y; scanf("%d%d",&x,&y); x++; y++;
add(x,y);
}
deep[1]=1;
dfs(1,0);
build(1,1);
scanf("%d",&t);
for (int i=1;i<=t;i++)
{
char s[10]; scanf("%s",s);
if (s[0]=='A'){
int x,y; LL z; scanf("%d%d%I64d",&x,&y,&z);
x++; y++;
solve(x,y,z);
}
else{
int x; scanf("%d",&x); x++;
printf("%I64d\n",query(1,1,n,l[x],r[x]));
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: