zoukankan      html  css  js  c++  java
  • xtu数据结构 I. A Simple Tree Problem

    I. A Simple Tree Problem

    Time Limit: 3000ms
    Memory Limit: 65536KB
    64-bit integer IO format: %lld      Java class name: Main
     

    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
    
    
     解题:利用dfs记录时间戳,也就是记录区间长度,恰好的包含关系,为建立线段树带来很大的方便,不需要建立N棵线段树,但以某一点为根节点的字孩子区间一定是父节点的区间的子区间。这样好的性质,恰好可以映射到线段树上。。。。。
     
     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cstdlib>
     5 #include <vector>
     6 #include <climits>
     7 #include <algorithm>
     8 #include <cmath>
     9 #define LL long long
    10 #define INF 0x3f3f3f
    11 using namespace std;
    12 const int maxn = 100010;
    13 int n,m,id;
    14 vector<int>g[maxn];
    15 int len[maxn<<2],cnt[maxn<<2],mark[maxn<<2];
    16 struct node{
    17     int lt,rt;
    18 }tree[maxn<<2];
    19 void dfs(int u){
    20     tree[u].lt = ++id;
    21     for(int i = 0; i < g[u].size(); i++){
    22         dfs(g[u][i]);
    23     }
    24     tree[u].rt = id;
    25 }
    26 void build(int lt,int rt,int v){
    27     cnt[v] = mark[v] = 0;
    28     len[v] = rt-lt+1;
    29     if(lt == rt) return;
    30     int mid = (lt+rt)>>1;
    31     build(lt,mid,v<<1);
    32     build(mid+1,rt,v<<1|1);
    33 }
    34 void push_down(int v){
    35     if(mark[v]){
    36         cnt[v<<1] = len[v<<1]-cnt[v<<1];
    37         mark[v<<1] ^= 1;
    38         cnt[v<<1|1] = len[v<<1|1]-cnt[v<<1|1];
    39         mark[v<<1|1] ^= 1;
    40         mark[v] = 0;
    41     }
    42 }
    43 void update(int x,int y,int lt,int rt,int v){
    44     if(lt >= x && rt <= y){
    45         cnt[v] = len[v] - cnt[v];
    46         if(lt == rt) return;
    47         mark[v] ^= 1;
    48         return;
    49     }
    50     push_down(v);
    51     int mid = (lt+rt)>>1;
    52     if(x <= mid) update(x,y,lt,mid,v<<1);
    53     if(y > mid) update(x,y,mid+1,rt,v<<1|1);
    54     cnt[v] = cnt[v<<1]+cnt[v<<1|1];
    55 }
    56 int query(int x,int y,int lt,int rt,int v){
    57     int ans = 0;
    58     if(x <= lt && rt <= y){
    59         return cnt[v];
    60     }
    61     push_down(v);
    62     int mid = (lt+rt)>>1;
    63     if(x <= mid) ans += query(x,y,lt,mid,v<<1);
    64     if(y > mid) ans += query(x,y,mid+1,rt,v<<1|1);
    65     return ans;
    66 }
    67 int main(){
    68     int i,temp;
    69     char s;
    70     while(~scanf("%d%d",&n,&m)){
    71         for(i = 0; i <= n; i++)
    72             g[i].clear();
    73         for(i = 2; i <= n; i++){
    74             scanf("%d",&temp);
    75             g[temp].push_back(i);
    76         }
    77         id = 0;
    78         dfs(1);
    79         build(1,n,1);
    80         while(m--){
    81             cin>>s>>temp;
    82             if(s == 'o'){
    83                 update(tree[temp].lt,tree[temp].rt,1,n,1);
    84             }else cout<<query(tree[temp].lt,tree[temp].rt,1,n,1)<<endl;
    85         }
    86         cout<<endl;
    87     }
    88     return 0;
    89 }
    View Code
  • 相关阅读:
    RocketMQ延迟消息的代码实战及原理分析
    如何做技术选型?Sentinel 还是 Hystrix?
    什么是服务熔断?
    降级-熔断-限流-傻傻分不清楚
    java-分布式-降级 熔断 限流
    java-分布式-分布式事务
    常用限流算法的应用场景和实现原理
    使用Redis作为分布式锁的一些注意点
    ansible {{}}引用变量,变量中嵌套变量如何表示
    shell获得java进程号跟进程对应的线程号
  • 原文地址:https://www.cnblogs.com/crackpotisback/p/3859143.html
Copyright © 2011-2022 走看看