zoj3686(重新编号的线段树)

来源:互联网 发布:百旺金赋税控软件 编辑:程序博客网 时间:2024/05/22 17:40
 题意:一颗n个节点的树,每个点都有一个权值(0或者1),初始化为0,两个操作:1、取反以i为节点的子树的所有点的权值;2、求以i点为根的子树中1的个数。

 思路:dfs将所有节点重新编号,然后就是普通的成段更新。

代码如下:

#include<iostream>#include<algorithm>#include<cstring>#include<string>#include<stdio.h>#include<math.h>#include<vector>#define N 100005#define inf 0x7ffffff#define eps 1e-9#define pi acos(-1.0)using namespace std;vector<int> G[N];int hash[N],num[N];int id;void dfs(int cur){    num[cur] = 1;    hash[cur] = id++;    int len = G[cur].size();    for(int i = 0; i < len; i++)    {        dfs(G[cur][i]);        num[cur] += num[ G[cur][i] ];    }}struct node{    int l,r,flag,sum;}tree[4*N];void build(int o,int l,int r){    tree[o].l = l;    tree[o].r = r;    tree[o].flag = tree[o].sum = 0;    if(l == r)  return;    int m = (l+r)/2;    build(2*o,l,m);    build(2*o+1,m+1,r);}void pushup(int o){    tree[o].sum = tree[2*o].sum + tree[2*o+1].sum;}void pushdown(int o){    if(tree[o].flag)    {        tree[2*o].flag ^= 1;        tree[2*o].sum = tree[2*o].r - tree[2*o].l + 1 - tree[2*o].sum;        tree[2*o+1].flag ^= 1;        tree[2*o+1].sum = tree[2*o+1].r - tree[2*o+1].l + 1 - tree[2*o+1].sum;        tree[o].flag = 0;    }}void update(int o,int x,int y){    if(x <= tree[o].l && tree[o].r <= y)    {        tree[o].sum = tree[o].r - tree[o].l + 1 - tree[o].sum;        tree[o].flag ^= 1;        return;    }    pushdown(o);    int m = (tree[o].l+tree[o].r)/2;    if(x <= m)  update(2*o,x,y);    if(y > m)   update(2*o+1,x,y);    pushup(o);}int query(int o,int x,int y){    if(x <= tree[o].l && tree[o].r <= y)         return tree[o].sum;    pushdown(o);    int m = (tree[o].l+tree[o].r)/2;    int ans = 0;    if(x <= m)  ans += query(2*o,x,y);    if(y > m)   ans += query(2*o+1,x,y);   // pushup(o);    return ans;}int main(){//freopen("input.txt","r",stdin);//freopen("output.txt","w",stdout);    int n,m;    while(scanf("%d%d",&n,&m) != EOF)    {         int i;         for(i = 1; i <= n; i++)    G[i].clear();         for(i = 2; i <= n; i++)         {             int x;             scanf("%d",&x);             G[x].push_back(i);//xµÄ¶ù×Ó½Úµã         }         id = 1;         dfs(1);         build(1,1,n);         while(m--)         {             char s[10];             int x;             scanf("%s%d",s,&x);             if(s[0] == 'o')                update(1,hash[x],hash[x]+num[x]-1);             else                printf("%d\n",query(1,hash[x],hash[x]+num[x]-1));         }         printf("\n");    }    return 0;}


0 0