1. 程式人生 > >zoj 3686 - A Simple Tree Problem (dfs序+線段樹區間更新)

zoj 3686 - A Simple Tree Problem (dfs序+線段樹區間更新)

Given a rooted tree, each node has a boolean (0 or 1) labeled on it. Initially, all the labels are 0.

We define this kind of operation: given a subtree, negate all its labels.

And we want to query the numbers of 1's of a subtree.

Input

Multiple test cases.

First line, two integer N

 and M, denoting the numbers of nodes and numbers of operations and queries.(1<=N<=100000, 1<=M<=10000)

Then a line with N-1 integers, denoting the parent of node 2..N. Root is node 1.

Then M lines, each line are in the format "o node" or "q node", denoting we want to operate or query on the subtree with root of a certain node.

Output

For each query, output an integer in a line.

Output a blank line after each test case.

Sample Input

3 2
1 1
o 2
q 1
Sample Output

1




好久沒寫線段樹區間更新了,找個裸題練練手

#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;

#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int maxn = 1e5+5;
vector<int> p[maxn];
int n,m,tol;
int siz[maxn],idx[maxn];
int tree[maxn<<2],lazy[maxn<<2];

void build(int l,int r,int rt)
{
    if(l==r)
    {
        tree[rt] = 0;
        lazy[rt] = 0;
        return ;
    }
    int m = (l+r)>>1;
    build(lson);
    build(rson);
    tree[rt] = tree[rt<<1]+tree[rt<<1|1];
    lazy[rt] = 0;
}

int dfs(int u)
{
    int ans = 0;
    idx[u] = ++tol;
    for(int i=0; i<p[u].size(); i++)
    {
        int v = p[u][i];
        ans += dfs(v)+1;
    }
    return siz[u] = ans;
}

void pushDown(int rt,int l,int r)
{
    if(lazy[rt]%2)
    {
        int m = (l+r)>>1;
        lazy[rt<<1]++;
        lazy[rt<<1|1]++;
        tree[rt<<1] = (m-l+1) - tree[rt<<1];
        tree[rt<<1|1] = (r-m) - tree[rt<<1|1];
        lazy[rt] = 0;
    }
}

int query(int L,int R,int l,int r,int rt)
{
    if(L<=l&&r<=R)
    {
        return tree[rt];
    }
    pushDown(rt,l,r);
    int m = (l+r)>>1;
    int ret = 0;
    if(L<=m)
        ret += query(L,R,lson);
    if(R>m)
        ret += query(L,R,rson);
    tree[rt] = tree[rt<<1]+tree[rt<<1|1];
    return ret;
}

void update(int L,int R,int l,int r,int rt)
{
    if(L<=l&&r<=R)
    {
        lazy[rt]++;
        tree[rt] = (r-l+1)-tree[rt];
        return;
    }
    pushDown(rt,l,r);
    int m = (l+r)>>1;
    if(L<=m)
        update(L,R,lson);
    if(R>m)
        update(L,R,rson);
    tree[rt] = tree[rt<<1]+tree[rt<<1|1];
}

int main()
{
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        tol = 0;
        for(int i=1; i<=n; i++)
            p[i].clear();
        build(1,n,1);
        for(int i=2; i<=n; i++)
        {
            int v;
            scanf("%d",&v);
            p[v].push_back(i);
        }
        dfs(1);
        while(m--)
        {
            char s[2];
            int u;
            scanf("%s%d",s,&u);
            if(s[0]=='o')
            {
                update(idx[u],idx[u]+siz[u],1,n,1);
            }
            else if(s[0]=='q')
            {
                printf("%d\n",query(idx[u],idx[u]+siz[u],1,n,1));
            }
        }
        puts("");
    }
    return 0;
}