zoukankan      html  css  js  c++  java
  • [NOI2015,LuoguP2146]软件包管理器------树剖

    ***题目链接戳我***

      又是在树上瞎搞滴题目....

      我们如果以安装的软件为1,未安装的软件为0,那么软件改变的数量即树上权值总和的数量,涉及到区间修改,区间查询,考虑树剖

      分析完毕,似乎没啥好说的了。。。树剖模板题(然鹅我是不会告诉你们我因为把int打成char查了好久好久代码滴...)   

      细节问题:为了便于处理把每个节点编号都加上1,避免一些不必要的错误

      P.S.打完才发现好像不用区间查询

      代码:

     1 #include<cstdio>
     2 #include<cctype>
     3 #include<iostream>
     4 using namespace std;
     5 inline int read(){
     6     int ans=0,f=1;char chr=getchar();
     7     while(!isdigit(chr)){if(chr=='-')f=-1;chr=getchar();}
     8     while(isdigit(chr)) {ans=(ans<<3)+(ans<<1)+chr-48;chr=getchar();}
     9     return ans*f;
    10 }const int M=200005;int n,m;
    11 inline int abs(int x) {if(x<0) return -x;return x;}
    12 int head[M],ver[M],nxt[M],tot,fa[M],dep[M],son[M],top[M],idx[M],sz[M],t,sum[M<<2],lz[M<<2];    
    13 inline void add(int x,int y){ver[++tot]=y;nxt[tot]=head[x];head[x]=tot;}
    14 void dfs1(int x){
    15     dep[x]=dep[fa[x]]+1;sz[x]=1;
    16     for(int i=head[x];i;i=nxt[i]){
    17         if(ver[i]==fa[x]) continue;
    18         fa[ver[i]]=x,dfs1(ver[i]);sz[x]+=sz[ver[i]];
    19         if(sz[ver[i]]>sz[son[x]]) son[x]=ver[i];
    20     }
    21 }void dfs2(int x,int topf){
    22     idx[x]=++t;top[x]=topf;
    23     if(!son[x]) return;dfs2(son[x],topf);
    24     for(int i=head[x];i;i=nxt[i])
    25         if(!idx[ver[i]]) dfs2(ver[i],ver[i]);
    26 }inline void Push_Up(int i){sum[i]=sum[i<<1]+sum[i<<1|1];}
    27  inline void Push_Down(int i,int l,int r){
    28      if(lz[i]==0) return;int mid=l+r>>1;
    29      if(lz[i]==-1) sum[i<<1]=sum[i<<1|1]=0,lz[i<<1]=lz[i<<1|1]=-1;
    30      else sum[i<<1]=mid-l+1,sum[i<<1|1]=r-mid,lz[i<<1]=lz[i<<1|1]=1;
    31      lz[i]=0;return;
    32 }void Update(int i,int l,int r,int ql,int qr,int x){
    33     if(ql<=l&&r<=qr){
    34         if(!x)lz[i]=-1,sum[i]=0;//lz==-1-->Update->0  lz==1 --> Update->1
    35         else lz[i]=1,sum[i]=r-l+1;
    36         return;
    37     }int mid=l+r>>1;Push_Down(i,l,r);
    38     if(mid>=ql) Update(i<<1,l,mid,ql,qr,x);
    39     if(mid<qr)  Update(i<<1|1,mid+1,r,ql,qr,x);
    40     Push_Up(i);
    41 }void Change(int v,int x,int y){
    42     while(top[x]!=top[y]){
    43         if(dep[top[x]]<dep[top[y]]) swap(x,y);
    44         Update(1,1,n,idx[top[x]],idx[x],v);
    45         x=fa[top[x]];
    46     }if(dep[x]>dep[y]) swap(x,y);Update(1,1,n,idx[x],idx[y],v);
    47 }
    48 int main(){
    49 //    freopen("rjb.in","r",stdin);
    50     n=read();
    51     for(int i=2;i<=n;i++){int x=read();++x;add(x,i);add(i,x);}
    52     dfs1(1),dfs2(1,1);
    53     m=read();char opt[20];int x,bf;
    54     while(m--){scanf("%s",opt);x=read();bf=sum[1];++x; 
    55         if(opt[0]=='i'){
    56             Change(1,x,1);
    57             printf("%d
    ",abs(sum[1]-bf));
    58         }else{
    59             Update(1,1,n,idx[x],idx[x]+sz[x]-1,0);
    60             printf("%d
    ",abs(sum[1]-bf));
    61         }
    62     }
    63     return 0;
    64 }
  • 相关阅读:
    (Java实现) 洛谷 P1106 删数问题
    (Java实现) 洛谷 P1603 斯诺登的密码
    (Java实现) 洛谷 P1036 选数
    (Java实现) 洛谷 P1012 拼数
    (Java实现) 洛谷 P1028 数的计算
    (Java实现) 洛谷 P1553 数字反转(升级版)
    (Java实现) 洛谷 P1051 谁拿了最多奖学金
    (Java实现) 洛谷 P1051 谁拿了最多奖学金
    (Java实现) 洛谷 P1106 删数问题
    目测ZIP的压缩率
  • 原文地址:https://www.cnblogs.com/zhenglw/p/10356806.html
Copyright © 2011-2022 走看看