# bzoj4034 [HAOI2015]树上操作

## 4034: [HAOI2015]树上操作

Time Limit: 10 Sec  Memory Limit: 256 MB
Submit: 6323  Solved: 2094
[Submit][Status][Discuss]

5 5
1 2 3 4 5
1 2
1 4
2 3
2 5
3 3
1 2 1
3 5
2 1 2
3 3

6
9
13

## HINT

对于 100% 的数据， N,M<=100000 ，且所有输入数据的绝对值都不会超过 10^6 。

## Source

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

const long long maxn = 200010;

long long n,m,head[maxn],nextt[maxn],to[maxn],tot = 1,a[maxn],L[maxn << 2],R[maxn << 2],pos[maxn],ppos[maxn],fa[maxn];
long long sizee[maxn],deep[maxn],top[maxn],son[maxn],cnt,endd[maxn];
long long sum[maxn << 2],tag[maxn << 2];

void add(long long x,long long y)
{
to[tot] = y;
}

void dfs(long long u,long long faa,long long dep)
{
sizee[u] = 1;
deep[u] = dep;
for (long long i = head[u];i;i = nextt[i])
{
long long v = to[i];
if (v == faa)
continue;
fa[v] = u;
dfs(v,u,dep + 1);
sizee[u] += sizee[v];
if (sizee[v] > sizee[son[u]])
son[u] = v;
}
}

void dfs2(long long u,long long topp)
{
top[u] = topp;
pos[u] = ++cnt;
ppos[cnt] = u;
if (son[u])
dfs2(son[u],topp);
for (long long i = head[u];i;i = nextt[i])
{
long long v = to[i];
if (v == fa[u] || v == son[u])
continue;
dfs2(v,v);
}
endd[u] = cnt;
}

void pushdown(long long o)
{
if (tag[o])
{
tag[o * 2] += tag[o];
tag[o * 2 + 1] += tag[o];
sum[o * 2] += tag[o] * (R[o * 2] - L[o * 2] + 1);
sum[o * 2 + 1] += tag[o] * (R[o * 2 + 1] - L[o * 2 + 1] + 1);
tag[o] = 0;
}
}

void pushup(long long o)
{
sum[o] = sum[o * 2] + sum[o * 2 + 1];
}

void build(long long o,long long l,long long r)
{
L[o] = l;
R[o] = r;
if (l == r)
{
sum[o] = a[ppos[l]];
return;
}
long long mid = (l + r) >> 1;
build(o * 2,l,mid);
build(o * 2 + 1,mid + 1,r);
pushup(o);
}

void update(long long o,long long l,long long r,long long x,long long y,long long v)
{
if (x <= l && r <= y)
{
tag[o] += v;
sum[o] += v * (r - l + 1);
return;
}
pushdown(o);
long long mid = (l + r) >> 1;
if (x <= mid)
update(o * 2,l,mid,x,y,v);
if (y > mid)
update(o * 2 + 1,mid + 1,r,x,y,v);
pushup(o);
}

long long query(long long o,long long l,long long r,long long x,long long y)
{
if (x <= l && r <= y)
return sum[o];
pushdown(o);
long long mid = (l + r) >> 1,res = 0;
if (x <= mid)
res += query(o * 2,l,mid,x,y);
if (y > mid)
res += query(o * 2 + 1,mid + 1,r,x,y);
return res;
}

long long queryy(long long x)
{
long long res = 0;
while (top[x] != 1)
{
res += query(1,1,n,pos[top[x]],pos[x]);
x = fa[top[x]];
}
res += query(1,1,n,pos[1],pos[x]);
return res;
}

int main()
{
scanf("%lld%lld",&n,&m);
for (long long i = 1; i <= n; i++)
scanf("%lld",&a[i]);
for (long long i = 1; i < n; i++)
{
long long x,y;
scanf("%lld%lld",&x,&y);
}
dfs(1,0,1);
dfs2(1,1);
build(1,1,n);
for (long long i = 1; i <= m; i++)
{
long long id,x,y;
scanf("%lld",&id);
if (id == 1)
{
scanf("%lld%lld",&x,&y);
update(1,1,n,pos[x],pos[x],y);
}
if (id == 2)
{
scanf("%lld%lld",&x,&y);
update(1,1,n,pos[x],endd[x],y);
}
if (id == 3)
{
scanf("%lld",&x);
printf("%lld\n",queryy(x));
}
}

return 0;
}

posted @ 2018-01-19 12:49  zbtrs  阅读(108)  评论(0编辑  收藏  举报