题意:

给出一个具有N个点的树,现在给出两种操作:

1.get x,表示询问以x作为根的子树中,1的个数。

2.pow x,表示将以x作为根的子树全部翻转(0变1,1变0).

思路:dfs序加上一个线段树区间修改查询。

AC代码:

#include<iostream>
#include<vector>
#include<string.h>
using namespace std;
const int maxn=2e5+5;
int sum[maxn<<2],lazy[maxn<<2],a[maxn],num[maxn],lft[maxn],rght[maxn],tot;
char s[10];
vector<int>map[maxn];

void build(int k,int l,int r){
    if(l==r){
        sum[k]=a[num[l]];
        return ;
    }
    int mid=(l+r)/2;
    build(k*2,l,mid);
    build(k*2+1,mid+1,r);
    sum[k]=sum[k*2]+sum[k*2+1];
}

void pushdown(int k,int l,int r){
    if(lazy[k]){
        int mid=(l+r)/2;
        sum[k*2]=mid-l+1-sum[k*2];
        sum[k*2+1]=r-mid-sum[k*2+1];
        //sum[k]=sum[k*2]+sum[k*2+1];
        lazy[k*2]^=1;
        lazy[k*2+1]^=1;
        lazy[k]=0;
    }
}

void update(int k,int l,int r,int L,int R){
    if(L<=l&&r<=R){
        sum[k]=r-l+1-sum[k];
        lazy[k]^=1;
        return;
    }
    pushdown(k,l,r);
    int mid=(l+r)/2;
    if(mid>=L)update(k*2,l,mid,L,R);
    if(mid<R)update(k*2+1,mid+1,r,L,R);
    sum[k]=sum[k*2]+sum[k*2+1];
    return ;
}

int query(int k,int l,int r,int L,int R){
    if(L<=l&&r<=R)return sum[k];
    int ans=0;
    pushdown(k,l,r);
    int mid=(l+r)/2;
    if(mid>=L)ans+=query(k*2,l,mid,L,R);
    if(mid<R)ans+=query(k*2+1,mid+1,r,L,R);
    //sum[k]=sum[k*2]+sum[k*2+1];
    return ans;
}
//pushdown和query的pushup可以不要,但是在update中pushdown之后需要pushup
 
void dfs(int k){
    lft[k]=++tot;
    for(int i=0;i<map[k].size();i++){
        dfs(map[k][i]);
    }
    rght[k]=tot;
}
//每个点的left序号就是在线段树中的序号
//每个点对应的left[i]-right[i]+1就是每个点的字节点的个数(加上自己)
 
int main(){
    int n,x;
    while(cin>>n){
        for(int i=1;i<=n;i++)map[i].clear();
        for(int i=2;i<=n;i++){
            cin>>x;
            map[x].push_back(i);
        }
        memset(sum,0,sizeof(sum));
        memset(lazy,0,sizeof(lazy));
        tot=0;
        dfs(1);
        /*for(int i=1;i<=n;i++){
            cout<<lft[i]<<' '<<rght[i]<<endl;
        }*/
        for(int i=1;i<=n;i++){
            cin>>a[i];
        }
        for(int i=1;i<=n;i++){
            num[lft[i]]=i;
            //每个点在线段树中的序号和本身不是一样的
            //注意看build函数
        }
        build(1,1,n);
        int q;
        cin>>q;
        for(int i=0;i<q;i++){
            cin>>s>>x;
            if(s[0]=='p'){
                update(1,1,n,lft[x],rght[x]);
            }
            else cout<<query(1,1,n,lft[x],rght[x])<<endl;
        }
    }
    return 0;
}

圆圈中的数字是每个节点的left值,每个点的right值就是每个点的子节点中left最大的那个

该图对应输入

10
1 2 3 4 2 4 1 7 8
1 1 0 1 1 0 0 0 1 1
10
pow 1
get 2
pow 2
pow 8
get 6
pow 6
pow 10
get 6
pow 8
pow 3
输出 3 0 1

(第一次看dfs序,看了好久才明白,还耽误了吴老狗睡觉的时间T^T,还是太菜了)

Codeforces Round #442 (Div. 2) E Danil and a Part-time Job (dfs序加上一个线段树区间修改查询)的更多相关文章

  1. Codeforces Round #169 (Div. 2) E. Little Girl and Problem on Trees dfs序+线段树

    E. Little Girl and Problem on Trees time limit per test 2 seconds memory limit per test 256 megabyte ...

  2. Codeforces Round #442 (Div. 2)A,B,C,D,E(STL,dp,贪心,bfs,dfs序+线段树)

    A. Alex and broken contest time limit per test 2 seconds memory limit per test 256 megabytes input s ...

  3. Codeforces Round #622 (Div. 2) A. Fast Food Restaurant(全排列,DFS)

    Codeforces Round #622 (Div. 2) A. Fast Food Restaurant 题意: 你是餐馆老板,虽然只会做三道菜,上菜时还有个怪癖:一位客人至少上一道菜,且一种菜最 ...

  4. Codeforces Round #442 (Div. 2) Danil and a Part-time Job

    http://codeforces.com/contest/877/problem/E 真的菜的不行,自己敲一个模板,到处都是问题.哎 #include <bits/stdc++.h> u ...

  5. Codeforces Round #442 Div.2 A B C D E

    A. Alex and broken contest 题意 判断一个字符串内出现五个给定的子串多少次. Code #include <bits/stdc++.h> char s[110]; ...

  6. Codeforces Round #877 (Div. 2) E. Danil and a Part-time Job

    E. Danil and a Part-time Job 题目链接:http://codeforces.com/contest/877/problem/E time limit per test2 s ...

  7. Codeforces Round #442 (Div. 2)

    A. Alex and broken contest time limit per test 2 seconds memory limit per test 256 megabytes input s ...

  8. 【Codeforces Round #442 (Div. 2) A】Alex and broken contest

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 注意是所有的名字里面,只出现了其中某一个名字一次. [代码] #include <bits/stdc++.h> usin ...

  9. 【Codeforces Round #442 (Div. 2) D】Olya and Energy Drinks

    [链接] 我是链接,点我呀:) [题意] 给一张二维点格图,其中有一些点可以走,一些不可以走,你每次可以走1..k步,问你起点到终点的最短路. [题解] 不能之前访问过那个点就不访问了.->即k ...

随机推荐

  1. 记录一次MyEclipse打开jsp文件出现Error的解决办法

    今天正在忙着写项目,在打开一个项目内的jsp文件时发现我亲爱的代码消失了. 最后从网上找到了解决办法,希望可以帮到有需要的人,也作为个人记录 第一步:找到安装路径MyEclipse\configura ...

  2. CentOS下Redis的安装(转)

    目录 CentOS下Redis的安装 前言 下载安装包 解压安装包并安装 启动和停止Redis 启动Redis 停止Redis 参考资料 CentOS下Redis的安装 前言 安装Redis需要知道自 ...

  3. Ubuntu 15.10 下Scala 操作Redis Cluster

    1 前言 Redis Standalone,Redis Cluster的安装在前面介绍过,地址:http://www.cnblogs.com/liuchangchun/p/5063477.html,这 ...

  4. 饿了么测试专场技术沙龙实况回顾&PPT 下载

    PPT下载和视频观看链接 链接:https://pan.baidu.com/s/1dE8uXHZ 密码:6j5z视频直播回顾: http://www.itdks.com/dakashuo/playba ...

  5. Kong(V1.0.2) Securing the Admin API

    Introduction Kong的Admin API为Services, Routes, Plugins, Consumers, and Credentials的管理和配置提供了一个RESTful接 ...

  6. markdwon语法与Typora

    我也是在视频中看到别人的操作,不知道这是个什么玩意? 直到无意间看到了markdown,才意识到其他人用的是markdown. 当你看到一个人使用类似 ![blockchain](https://ss ...

  7. Java核心-多线程-并发控制器-CyclicBarrier同步屏障

    1.基本概念 中文译本同步屏障,同样来自jdk并发工具包中一个并发控制器,它的使用和CountDownLatch有点相似,能够完成某些相同并发场景,但是它们却不相同. 2.抽象模型 主要用来实现多个线 ...

  8. 设计stark组件

    设计stark组件 作者:Eric 微信:loveoracle11g 新建Django项目crm_1随便起名 然后再创建一个App manage.py@crm_1 > startapp star ...

  9. Qt之QTreeWidget入门

    QTreeWidget的一些基本操作 1.insertTopLevelItems,insertTopLevelItem用来添加顶层的item QTreeWidget *treeWidget = new ...

  10. Redis主从+读写分离中可以在从机读取到过期数据

    参考链接: https://mp.weixin.qq.com/s?__biz=MzIyNzUwMjM2MA==&mid=2247483696&idx=1&sn=c69e364b ...