SHOI 2012 Magic Tree

Luo Gu P3833 [SHOI2012] magic tree

Luo Gu Portal

Topic background

SHOI2012 D2T3

Title Description

Harry Potter a new school of magic: You can make changes in the number of fruit trees. Full of joy, he found a huge fruit trees, to test his new spell.

A total of N nodes fruit tree, where 0 is the root node, each node's father referred to as FA u [u], ensure fa [u] <u. Initially, the fruit on the tree fruit trees have been cleared away by Dumbledore magic, so no fruit on the fruit trees of each node (ie, 0 fruit).

Unfortunately, Harry's magic school get bit, only for the number of fruit on the tree node for a path of unity to increase a certain amount. In other words, Harry's magic can be described as:

Add u v d

The number of fruit showing all the nodes on the path between u and v are plus d.

Next, in order to facilitate the successful test whether Harry's magic, you need to tell him something about fruit trees in the process of release of magic in:

Query u

It represents the current fruit trees, the sub-tree rooted at the point u, the total number of fruit?

Input Format

The first line of a positive integer N (1 ≤ N ≤ 100000), indicates the total number of fruit node, nodes 0,1, ..., N - 1 numbers, 0 necessarily represent the root node.

Next, N - 1 lines of two integers a, b (0 ≤ a <b <N), b represents is a father.

Next is a positive integer Q (1 ≤? ≤ 100000), Q represents the total operations.

Followed by Q rows, each row is one of two of:

  1. A uvd, represents the number of all nodes on the fruit u to v plus the path d; 0 ≤ u, v <N, 0 <d <100000
  2. Q u, represents the total number of fruit interrogation subtree rooted in u, u is a note itself.

Output Format

Query for all operations, in turn answer to the query output, one per line. The answer may be more than 2 ^ 32, but not more than 10 ^ 15.

Sample input and output

Input # 1 copy

Output # 1 copy

answer:

A bare tree chain split title.

Of course, a more simple multiplication of LCA practice if some of the data, if the water is hard on, suggest that you take the opportunity to learn about the tree split chain.

(Incidentally, he pushed himself to speak of the split tree chainBetterBlog, blog reading tastes better):

On the tree split chain

This question this code! !

And then given the code on this question:

Incidentally conferred on the code yourself ugly:

#include<cstdio>
#include<iostream>
#include<algorithm>
#define int long long
#define lson pos<<1
#define rson pos<<1|1
using namespace std;
const int maxn=1e5+1;
int n,tot,cnt,q;
int head[maxn],nxt[maxn<<1],to[maxn<<1];
int fa[maxn],deep[maxn],size[maxn],son[maxn];
int id[maxn],top[maxn];
int tree[maxn<<2],lazy[maxn<<2];
void add(int x,int y)
{
    to[++tot]=y;
    nxt[tot]=head[x];
    head[x]=tot;
}
void dfs1(int x,int f)
{
    deep[x]=deep[f]+1;
    fa[x]=f;
    size[x]=1;
    for(int i=head[x];i;i=nxt[i])
    {
        int y=to[i];
        if(y==f)
            continue;
        dfs1(y,x);
        size[x]+=size[y];
        if(!son[x]||size[son[x]]<size[y])
            son[x]=y;
    }
}
void dfs2(int x,int t)
{
    id[x]=++cnt;
    top[x]=t;
    if(!son[x])
        return;
    dfs2(son[x],t);
    for(int i=head[x];i;i=nxt[i])
    {
        int y=to[i];
        if(y==fa[x]||y==son[x])
            continue;
        dfs2(y,y);
    }
}
void mark(int pos,int l,int r,int k)
{
    tree[pos]+=(r-l+1)*k;
    lazy[pos]+=k;
}
void pushdown(int pos,int l,int r)
{
    int mid=(l+r)>>1;
    mark(lson,l,mid,lazy[pos]);
    mark(rson,mid+1,r,lazy[pos]);
    lazy[pos]=0;
}
void update(int pos,int l,int r,int x,int y,int k)
{
    int mid=(l+r)>>1;
    if(x<=l && r<=y)
    {
        mark(pos,l,r,k);
        return;
    }
    pushdown(pos,l,r);
    if(x<=mid)
        update(lson,l,mid,x,y,k);
    if(y>mid)
        update(rson,mid+1,r,x,y,k);
    tree[pos]=tree[lson]+tree[rson];
}
void upd_chain(int x,int y,int k)
{
    while(top[x]!=top[y])
    {
        if(deep[top[x]]<deep[top[y]])
            swap(x,y);
        update(1,1,n,id[top[x]],id[x],k);
        x=fa[top[x]];
    }
    if(deep[x]<deep[y])
        swap(x,y);
    update(1,1,n,id[y],id[x],k);
}
int query(int pos,int l,int r,int x,int y)
{
    int ret=0;
    int mid=(l+r)>>1;
    if(x<=l && r<=y)
        return tree[pos];
    pushdown(pos,l,r);
    if(x<=mid)
        ret+=query(lson,l,mid,x,y);
    if(y>mid)
        ret+=query(rson,mid+1,r,x,y);
    return ret;
}
int q_subtree(int x)
{
    return query(1,1,n,id[x],id[x]+size[x]-1);
}
signed main()
{
    scanf("%lld",&n);
    for(int i=1;i<n;i++)
    {
        int x,y;
        scanf("%lld%lld",&x,&y);
        x++,y++;
        add(x,y);
        add(y,x);
    }
    dfs1(1,0);
    dfs2(1,1);
    scanf("%lld",&q);
    while(q--)
    {
        char k;
        cin>>k;
        if(k=='A')
        {
            int x,y,d;
            scanf("%lld%lld%lld",&x,&y,&d);
            x++,y++;
            upd_chain(x,y,d);
        }
        else
        {
            int x;
            scanf("%lld",&x);
            x++;
            printf("%lld\n",q_subtree(x));
        }
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/fusiwei/p/11607657.html