博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
codeforces 877e
阅读量:6327 次
发布时间:2019-06-22

本文共 4638 字,大约阅读时间需要 15 分钟。

E. Danil and a Part-time Job
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Danil decided to earn some money, so he had found a part-time job. The interview have went well, so now he is a light switcher.

Danil works in a rooted tree (undirected connected acyclic graph) with n vertices, vertex 1 is the root of the tree. There is a room in each vertex, light can be switched on or off in each room. Danil's duties include switching light in all rooms of the subtree of the vertex. It means that if light is switched on in some room of the subtree, he should switch it off. Otherwise, he should switch it on.

Unfortunately (or fortunately), Danil is very lazy. He knows that his boss is not going to personally check the work. Instead, he will send Danil tasks using Workforces personal messages.

There are two types of tasks:

  1. pow v describes a task to switch lights in the subtree of vertex v.
  2. get v describes a task to count the number of rooms in the subtree of v, in which the light is turned on. Danil should send the answer to his boss using Workforces messages.

A subtree of vertex v is a set of vertices for which the shortest path from them to the root passes through v. In particular, the vertex v is in the subtree of v.

Danil is not going to perform his duties. He asks you to write a program, which answers the boss instead of him.

Input

The first line contains a single integer n (1 ≤ n ≤ 200 000) — the number of vertices in the tree.

The second line contains n - 1 space-separated integers p2, p3, ..., pn (1 ≤ pi < i), where pi is the ancestor of vertex i.

The third line contains n space-separated integers t1, t2, ..., tn (0 ≤ ti ≤ 1), where ti is 1, if the light is turned on in vertex i and 0otherwise.

The fourth line contains a single integer q (1 ≤ q ≤ 200 000) — the number of tasks.

The next q lines are get v or pow v (1 ≤ v ≤ n) — the tasks described above.

Output

For each task get v print the number of rooms in the subtree of v, in which the light is turned on.

Example
input
4 1 1 1 1 0 0 1 9 get 1 get 2 get 3 get 4 pow 1 get 1 get 2 get 3 get 4
output
2 0 0 1 2 1 1 0 题意:n点    输入每个点的值0或1   输入每个点的父节点    m次操作    pow操作改变q节点后面的全部节点包括q节点   get操作是问q节点的子节点包括q一共有多少个1

这个题要用线段树+dfs,意思就是为每个点分配一个区间,区间大的包含区间小的

这个题要注意的是

每个点可能变换多次,你不需要全都变换,查询时候在一次性的变完就行,否则可能会超时,反正我链表这样做超时了,数组我好像runtime error了   最后也懒得改了,又敲了一遍过的,然后就没什么注意的了,这题就是这样

 

 

丑陋的代码

#include <iostream>

#include <vector>

using namespace std;

void pushdown(int i);

const int N = 2e5 + 10;

int a[N],in[N],out[N],pre[N],cnt = 0;

vector<int> p[N];

struct node

{

    int l = 0,r = 0;

    int sum = 0;

    int lazy = 0;

}pp[N<<2];

void dfs(int n)

{

    for(int i = 0; i < p[n].size(); ++i)

    {

        int d = p[n][i];

        cnt ++;

        in[d] = cnt;

        pre[cnt] = d;

        dfs(d);

        out[d] = cnt;

    }

}

void build(int i)

{

    int mid = (pp[i].l+pp[i].r)>>1;

    int l = pp[i].l;

    int r = pp[i].r;

    

    if(pp[i].l == pp[i].r)

    {

        pp[i].sum = a[pre[l]];

        return ;

    }

    pp[(i<<1)].l = l;

    pp[(i<<1)].r = mid;

    

    pp[(i<<1)+1].l = mid+1;

    pp[(i<<1)+1].r = r;

    

    

    build((i<<1));

    build((i<<1)+1);

    pp[i].sum += pp[i<<1].sum + pp[(i<<1)+1].sum;

}

void update(int l,int r,int i)

{

    int mid = (pp[i].l+pp[i].r) >> 1;

    if(pp[i].l == l && pp[i].r == r)

    {

        pp[i].sum = pp[i].r - pp[i].l + 1 - pp[i].sum;

        pp[i].lazy ^= 1;

        pushdown(i);

      //这个地方要注意pushdowm的操作位置     

        return ;

    }

    if(r <= mid)

    {

        update(l,r, i<<1);

    }

    else if(l >= mid + 1)

    {

        update(l,r,(i<<1)+1);

    }

    else

    {

        update(l, mid, i<<1);

        update(mid+1, r, (i<<1)+1);

    }

    pp[i].sum = pp[i<<1].sum + pp[(i<<1)+1].sum;

}

void pushdown(int i)

{

    if(pp[i].lazy)

    {

        pp[i].sum = pp[i].r - pp[i].l + 1 - pp[i].sum;

        pp[i<<1].lazy ^= 1;

        pp[(i<<1)+1].lazy ^= 1;

        pp[i].lazy ^= 1;

    }

}

int query(int l,int r,int i)

{

    int mid = (pp[i].l + pp[i].r)>>1;

    pushdown(i);

    if(pp[i].l == l && pp[i].r == r)

        return pp[i].sum;

    if(r <= mid)

    {

        return query(l, r, i<<1);

    }

    else if(l >= mid + 1)

    {

        return query(l, r, (i<<1)+1);

    }

    else

    {

        return query(l, mid, i<<1) + query(mid+1, r, (i<<1)+1);

    }

}

int main()

{

    int n,i,j,d,x,ppp;

    char str[20];

    scanf("%d",&n);

    for(i = 2; i <= n; ++i)

    {

        scanf("%d",&d);

        p[d].push_back(i);

    }

    for(i = 1; i <= n; ++i)

        scanf("%d",&a[i]);

    pre[1] = 1;

    cnt = 1;

    in[1] = 1;

    out[1] = n;

    pp[1].l = 1;

    pp[1].r = n;

    dfs(1);

    build(1);

    scanf("%d",&ppp);

    while( ppp-- )

    {

        scanf("%s",str);

        if(str[0] == 'g')

        {

            scanf("%d",&x);

            printf("%d\n",query(in[x], out[x], 1));

        }

        else

        {

            scanf("%d",&x);

            update(in[x], out[x], 1);

        }

    }

    return 0;

}

 

 

 

注意    update的时候假如(pp[i].l == l && pp[i].r == r)这个时候一定要更新当前节点     后面的节点可以不更新,但当前节点必须要更新

具体原因数据在这里     你画一下图就明白了

101 2 3 3 5 5 7 7 80 0 0 0 1 1 1 1 0 010pow 3get 1pow 9get 1get 1get 8pow 8pow 4get 10pow 2

转载于:https://www.cnblogs.com/mltang/p/7780385.html

你可能感兴趣的文章
关键字检索高亮标出-javasript/jQuery代码实现
查看>>
Vijos P1785 同学排序【模拟】
查看>>
人物关系网络图可视化
查看>>
关于ADO.Net SqlConnection的性能优化
查看>>
docker安装及加速配置
查看>>
MRF能量优化
查看>>
什么是.Net, IL, CLI, BCL, FCL, CTS, CLS, CLR, JIT
查看>>
Atlas Control ToolKit 发布
查看>>
Dundas 系列
查看>>
Windows的命令行查看,修改,删除,添加环境变量
查看>>
iOS 图文混排
查看>>
GC是什么? 为什么要有GC?
查看>>
JQuery EasyUi之界面设计——母版页以及Ajax的通用处理(三)
查看>>
童年记忆
查看>>
Selenium Python bindings 文档一
查看>>
directX的16位和24位的色彩模式
查看>>
WINDOWS 8
查看>>
ASP.NET MVC涉及到的5个同步与异步,你是否傻傻分不清楚?[下篇]
查看>>
spring(10)
查看>>
Ubuntu 12.04 LTS 及ubuntu14.10 -- NFS安装
查看>>