zoukankan      html  css  js  c++  java
  • codeforces 877E Danil and a Part-time Job

    codeforces 877E Danil and a Part-time Job

    题目传送门

    题意:

    给出一个树,每一个点都有权值,权值为0或1,要求支持两个操作:子树权值翻转,子树权值和。

    题解:

    比较水的一道E题吧,反正就是用线段树维护(Dfn)序就行了,差不多树剖那个套路吧。。

    Code:

    #include<bits/stdc++.h>
    using namespace std;
    const int N=2e5+500;
    int idx[N],x[N],v[N],sz[N],heav[N];
    int n,cnt,q;
    vector<int>G[N];
    
    namespace SegmentTree {
      struct node {
        int l,r,sz,cnt,flip;
      }t[N<<3];
    #define ls(o) (o)<<1
    #define rs(o) (o)<<1|1
      void Update(int o) {
        t[o].cnt=t[ls(o)].cnt+t[rs(o)].cnt;
      }
      void Pushdown(int o) {
        if(!t[o].flip) return ;
        t[ls(o)].cnt=t[ls(o)].sz-t[ls(o)].cnt;
        t[rs(o)].cnt=t[rs(o)].sz-t[rs(o)].cnt;
        t[ls(o)].flip^=1;
        t[rs(o)].flip^=1;
        t[o].flip^=1;
        return ;
      }
      void Build(int o,int l,int r) {
        t[o].l=l;t[o].r=r;t[o].sz=r-l+1;
        if(l==r) {
          t[o].cnt=v[l];
          return ;
        }
        int mid=(l+r)>>1;
        Build(ls(o),l,mid);
        Build(rs(o),mid+1,r);
        Update(o);
        return ;
      }
      void Modify(int o,int l,int r) {
        if(t[o].l>=l&&t[o].r<=r) {
          t[o].cnt=t[o].sz-t[o].cnt;
          t[o].flip^=1;
          return ;
        }
        Pushdown(o);
        int mid=(t[o].l+t[o].r)>>1;
        if(mid>=l) Modify(ls(o),l,r);
        if(mid<r) Modify(rs(o),l,r);
        Update(o);
        return ;
      }
      int Query(int o,int l,int r) {
        if(t[o].l>=l&&t[o].r<=r) return t[o].cnt;
        Pushdown(o);
        int mid=(t[o].l+t[o].r)>>1;
        int ans=0;
        if(mid>=l) ans+=Query(ls(o),l,r);
        if(mid<r) ans+=Query(rs(o),l,r);
        return ans;
      }
    }
    using namespace SegmentTree;
    
    namespace Solver {
      void Dfs1(int o,int fa) {
        sz[o]=1;
        int Mxson=-1;
        for(int i=0;i<(int)G[o].size();i++) {
          int to=G[o][i];
          if(to==fa) continue;
          Dfs1(to,o);
          sz[o]+=sz[to];
          if(sz[to]>Mxson) {
    	Mxson=sz[to];
    	heav[o]=to;
          }
        }
      }
      void Dfs2(int o) {
        idx[o]=++cnt;
        v[cnt]=x[o];
        if(!heav[o]) return ;
        Dfs2(heav[o]);
        for(int i=0;i<(int)G[o].size();i++) {
          int to=G[o][i];
          if(idx[to]) continue;
          Dfs2(to);
        }
      }
      void Init() {
        Dfs1(1,1);
        Dfs2(1);
        Build(1,1,n);
      }
      void Change(int o) {Modify(1,idx[o],idx[o]+sz[o]-1);}
      int Ask(int o) {return Query(1,idx[o],idx[o]+sz[o]-1);}
    }
    
    int main() {
      scanf("%d",&n);
      for(int i=2,p;i<=n;i++) {
        scanf("%d",&p);
        G[p].push_back(i);
        G[i].push_back(p);
      }
      for(int i=1;i<=n;i++) scanf("%d",&x[i]);
      Solver::Init();
      scanf("%d",&q);
      while(q--) {
        char s[10];
        int x;
        scanf("%s%d",s,&x);
        if(s[0]=='g') printf("%d
    ",Solver::Ask(x));
        else Solver::Change(x);
      }
      return 0;
    }
    
    
    「我不敢下苦功琢磨自己,怕终于知道自己并非珠玉;然而心中既存着一丝希冀,便又不肯甘心与瓦砾为伍。」
  • 相关阅读:
    OAuth 2 开发人员指南(Spring security oauth2)
    Android如何在ListView中嵌套ListView
    Android之ScrollView嵌套ListView冲突
    Android 去除EditText边框,添加下划线,
    Android日期时间选择器实现以及自定义大小
    验证Android用户输入日期
    Cygwin安装时,选择163的源后出错:Unable to get setup.ini from <http://mirrors.163.com/cygwin/>
    Windows平台下安装Hadoop
    如何在windows下安装cygwin
    连接Linux服务器:Win免费SSH客户端工具
  • 原文地址:https://www.cnblogs.com/Apocrypha/p/9742667.html
Copyright © 2011-2022 走看看