cdoj 574 High-level ancients dfs序+线段树

High-level ancients

Time Limit: 20 Sec

Memory Limit: 256 MB

题目连接

http://acm.uestc.edu.cn/#/problem/show/574

Description

Love8909 is keen on the history of Kingdom ACM. He admires the heroic undertakings of Lxhgww and Haibo. Inspired by those sagas, Love8909 picked up his courage and tried to build up his own kingdom. He named it as A230.

After hard working for several years, Love8909 is about to fulfill his dream. However, there is still one thing to do: setting up the defense network. As Kingdom EDC looks at territory and people of A230 fiercely as a tiger does, Love8909 has to make it as soon as possible.

The defense network Love8909 wants to use is the same as the one used by Lxhgww and Haibo. He also connects all cities with roads which form a tree structure, and the capital city is City 1, which is the root of this tree. Love8909 sends commands to inform cities to add soldiers. The command, being same to those of the ancients, with two values, X and K, means sending K soldiers to City X, sending K+1 soldiers to sons of City X, sending K+2 soldiers to sons of sons of City X and so on. Initially there are no soldiers in any city.

《cdoj 574 High-level ancients dfs序+线段树》

Love8909 may adjust the arrangement of soldiers ever and again. He asks questions about how many soldiers in the subtree rooted at City X. A subtree rooted at City X includes City X itself and all of its descendants. As Love8909’s military counselor, you are responsible to complete all his commands and answer his questions.

Input

The first line of the input will be an integer T (T20) indicating the number of cases.

For each case, the first line contains two integers: N P, representing the number of cities in A230 and number of operations given by love8909.

The next line lists N1 integers, in which the ith number, denoted as Xi+1, represents there is a road from City Xi+1 to City i+1. Note that the City 1has been omitted. 1Xi+1N for 2iN.

Then P lines follow, each gives an operation. Each operation belongs to either kind:

  • A X K. An adding-soldier command.
  • Q X. A question about how many soldiers in the subtree rooted at City X.

We guarantee that the cities form a rooted tree and the root is at City 1, which is the capital.

1N500001P1000001XN0K1000.

Output

For each case, print Case #k: first in a single line, in which k represents the case number which starts from 1. Then for each Query X operation, print the answer in a single line.

Sample Input

1
7 10
1 1 2 2 5 5
Q 1
A 2 1
Q 1
Q 2
Q 5
A 5 0
Q 5
A 3 1
Q 1
Q 2

Sample Output

Case #1:
0
11
11
8
10
14
13

HINT

 

题意

给你一棵以1为根的树,有两个操作

1.A x k,让x增加k,x的儿子增加k+1,x的孙子增加k+2….x的t代儿子增加k+t

2.Q x , 查询x的子树的权值和是多少

题解:

看到处理子树问题,很显然的dfs序

dfs离散之后,维护线段树区间和,区间更新

我们很容易看出,他的更新是和deep有关的,deep越深的,更新越大

那么我们对于每个节点i,先区间更新y-deep[x],然后再使得更新一次,使得每个节点i增加deep[i]就好了

这样每个属于x的子树的都更新了 y – deep[x] + deep[i]

代码:

#include<iostream>
#include<stdio.h>
#include<vector>
using namespace std;
#define maxn 100010
struct Node
{
    int l,r,d,val;
};
Node node[maxn];
vector<int>Q[maxn];
int TTT[maxn];
int cnt = 1;
void dfs(int x,int fa,int d)
{
    node[x].l = cnt;
    node[x].d = d;
    TTT[cnt]=x;
    cnt++;
    for(int i=0;i<Q[x].size();i++)
    {
        int v = Q[x][i];
        if(v==fa)continue;
        dfs(v,x,d+1);
    }
    node[x].r = cnt;
}
int d[maxn];
struct Seg
{
    typedef long long SgTreeDataType;
    struct treenode
    {
      int L , R  ;
      SgTreeDataType sum , lazy1 , lazy2;
    };

    treenode tree[maxn*4];

    inline void push_down(int o)
    {
        SgTreeDataType lazyval1 = tree[o].lazy1;
        SgTreeDataType lazyval2 = tree[o].lazy2;
        if(lazyval1==0&&lazyval2==0)return;
        int L = tree[o].L , R = tree[o].R;
        int mid = (L+R)/2;
        tree[2*o].lazy1+=lazyval1;tree[2*o].sum+=lazyval1*(mid-L+1);
        tree[2*o+1].lazy1+=lazyval1;tree[2*o+1].sum+=lazyval1*(R-mid);

        tree[2*o].lazy2+=lazyval2;tree[2*o].sum+=lazyval2*d[2*o];
        tree[2*o+1].lazy2+=lazyval2;tree[2*o+1].sum+=lazyval2*d[2*o+1];
        tree[o].lazy1 = tree[o].lazy2 = 0;
    }

    inline void push_up(int o)
    {
        tree[o].sum = tree[2*o].sum + tree[2*o+1].sum;
    }

    inline void build_tree(int L , int R , int o)
    {
        tree[o].L = L , tree[o].R = R,tree[o].sum = tree[o].lazy1 = tree[o].lazy2 = 0;
        if(L==R)
            d[o]=node[TTT[L]].d;
        if (R > L)
        {
            int mid = (L+R) >> 1;
            build_tree(L,mid,o*2);
            build_tree(mid+1,R,o*2+1);
            d[o]=d[o*2]+d[o*2+1];
        }
    }

    inline void updata1(int QL,int QR,SgTreeDataType v,int o)
    {
        int L = tree[o].L , R = tree[o].R;
        if (QL <= L && R <= QR)
        {
            tree[o].lazy1 += v;
            tree[o].sum += v * (R-L+1);
        }
        else
        {
            push_down(o);
            int mid = (L+R)>>1;
            if (QL <= mid) updata1(QL,QR,v,o*2);
            if (QR >  mid) updata1(QL,QR,v,o*2+1);
            push_up(o);
        }
    }

    inline void updata2(int QL,int QR,SgTreeDataType v,int o)
    {
        int L = tree[o].L , R = tree[o].R;
        if (QL <= L && R <= QR)
        {
            tree[o].lazy2+=v;
            tree[o].sum+=v*d[o];
        }
        else
        {
            push_down(o);
            int mid = (L+R)>>1;
            if (QL <= mid) updata2(QL,QR,v,o*2);
            if (QR >  mid) updata2(QL,QR,v,o*2+1);
            push_up(o);
        }
    }

    inline SgTreeDataType query(int QL,int QR,int o)
    {
        int L = tree[o].L , R = tree[o].R;
        if (QL <= L && R <= QR) return tree[o].sum;
        else
        {
            push_down(o);
            int mid = (L+R)>>1;
            SgTreeDataType res = 0;
            if (QL <= mid) res += query(QL,QR,2*o);
            if (QR > mid) res += query(QL,QR,2*o+1);
            push_up(o);
            return res;
        }
    }
}T;


int main()
{
    int t;scanf("%d",&t);
    for(int cas=1;cas<=t;cas++)
    {
        printf("Case #%d:\n",cas);
        int n,q;
        scanf("%d%d",&n,&q);
        for(int i=0;i<=n;i++)Q[i].clear(),node[i].val=0;
        cnt = 1;
        for(int i=2;i<=n;i++)
        {
            int x,y;scanf("%d",&x);
            y=i;
            Q[x].push_back(y);
            Q[y].push_back(x);
        }
        dfs(1,-1,1);
        T.build_tree(1,n,1);
        string ch;
        while(q--)
        {
            cin>>ch;
            if(ch[0]=='Q')
            {
                int x;scanf("%d",&x);
                printf("%lld\n",T.query(node[x].l,node[x].r-1,1));
            }
            else
            {
                int x,y;scanf("%d%d",&x,&y);
                T.updata1(node[x].l,node[x].r-1,y-node[x].d,1);
                T.updata2(node[x].l,node[x].r-1,1,1);
            }
        }
    }
}

 

    原文作者:qscqesze
    原文地址: https://www.cnblogs.com/qscqesze/p/4996401.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞