zoukankan      html  css  js  c++  java
  • [NOI2015]软件包管理器

    题目大意:
      给你一棵n个结点的树,按给定顺序进行以下两种操作:
        1.把根到x路径上的所有点的点权都变成1;
        2.把x的子树中,所有点的的点权都变成0。
      问每一步操作时,有多少点的点权发生了改变。

    思路:
      树链剖分。
      每次操作前先询问,再修改。
      注意结点是从0开始的,所以各种地方都要改。
      尤其注意son不能默认它是0,不然后面的子结点都和根结点在比,这样剖出来就不是轻重链了,会T得很惨。

      1 #include<cstdio>
      2 #include<cctype>
      3 #include<vector>
      4 #include<cstring>
      5 inline int getint() {
      6     register char ch;
      7     while(!isdigit(ch=getchar()));
      8     register int x=ch^'0';
      9     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
     10     return x;
     11 }
     12 const int N=100000;
     13 std::vector<int> e[N];
     14 char op[10];
     15 int n,size[N],par[N]={-1},dep[N]={1},son[N],id[N],top[N],cnt;
     16 void dfs1(const int &x) {
     17     size[x]=1;
     18     for(unsigned i=0;i<e[x].size();i++) {
     19         const int &y=e[x][i];
     20         par[y]=x;
     21         dep[y]=dep[x]+1;
     22         dfs1(y);
     23         size[x]+=size[y];
     24         if(!son[x]||size[y]>size[son[x]]) {
     25             son[x]=y;
     26         }
     27     }
     28 }
     29 void dfs2(const int &x) {
     30     id[x]=++cnt;
     31     if(son[x]) {
     32         top[son[x]]=top[x];
     33         dfs2(son[x]);
     34     }
     35     for(unsigned i=0;i<e[x].size();i++) {
     36         const int &y=e[x][i];
     37         if(y==son[x]) continue;
     38         top[y]=y;
     39         dfs2(y);
     40     }
     41 }
     42 class SegmentTree {
     43     #define _left <<1
     44     #define _right <<1|1
     45     private:
     46         int val[N<<2],tag[N<<2];
     47         int size(const int &b,const int &e) const {
     48             return e-b+1;
     49         }
     50         void push_down(const int &p,const int &b,const int &e) {
     51             if(tag[p]==-1) return;
     52             const int mid=(b+e)>>1;
     53             val[p _left]=tag[p]*size(b,mid);
     54             val[p _right]=tag[p]*size(mid+1,e);
     55             tag[p _left]=tag[p _right]=tag[p];
     56             tag[p]=-1;
     57         }
     58         void push_up(const int &p) {
     59             val[p]=val[p _left]+val[p _right];
     60         }
     61     public:
     62         SegmentTree() {
     63             memset(tag,-1,sizeof tag);
     64         }
     65         void modify(const int &p,const int &b,const int &e,const int &l,const int &r,const int &t) {
     66             if(b==l&&e==r) {
     67                 val[p]=t*size(b,e);
     68                 tag[p]=t;
     69                 return;
     70             }
     71             push_down(p,b,e);
     72             const int mid=(b+e)>>1;
     73             if(l<=mid) modify(p _left,b,mid,l,std::min(mid,r),t);
     74             if(r>mid) modify(p _right,mid+1,e,std::max(mid+1,l),r,t);
     75             push_up(p);
     76         }
     77         int query(const int &p,const int &b,const int &e,const int &l,const int &r) {
     78             if(b==l&&e==r) {
     79                 return val[p];
     80             }
     81             push_down(p,b,e);
     82             const int mid=(b+e)>>1;
     83             int ret=0;
     84             if(l<=mid) ret+=query(p _left,b,mid,l,std::min(mid,r));
     85             if(r>mid) ret+=query(p _right,mid+1,e,std::max(mid+1,l),r);
     86             return ret;
     87         }
     88     #undef _left
     89     #undef _right
     90 };
     91 SegmentTree t;
     92 inline void modify(int x) {
     93     while(~x) {
     94         t.modify(1,1,n,id[top[x]],id[x],1);
     95         x=par[top[x]];
     96     }
     97 }
     98 inline int query(int x) {
     99     int ret=0;
    100     while(~x) {
    101         ret+=t.query(1,1,n,id[top[x]],id[x]);
    102         x=par[top[x]];
    103     }
    104     return ret;
    105 }
    106 int main() {
    107     n=getint();
    108     for(register int i=1;i<n;i++) {
    109         e[getint()].push_back(i);
    110     }
    111     dfs1(0);
    112     dfs2(0);
    113     for(register int q=getint();q;q--) {
    114         scanf("%s",op);
    115         const int x=getint();
    116         if(op[0]=='i') {
    117             printf("%d
    ",dep[x]-query(x));
    118             modify(x);
    119         } else {
    120             printf("%d
    ",t.query(1,1,n,id[x],id[x]+size[x]-1));
    121             t.modify(1,1,n,id[x],id[x]+size[x]-1,0);
    122         }
    123     }
    124     return 0;
    125 }
  • 相关阅读:
    python进阶(1)--多进程与多线程概念
    mysql数据库(5)--表的相关操作
    mysql数据库(4)--表删除操作
    备注
    mysql数据库(3)--mysql的执行顺序
    mysql数据库(2)--窗口函数之序号函数
    Spring MVC 返回中文乱码
    郁闷,郁闷啊
    Struts2 下载文件
    js文件加载
  • 原文地址:https://www.cnblogs.com/skylee03/p/8067382.html
Copyright © 2011-2022 走看看