• bzoj4196 软件包管理器


    题意:给你一棵树。两种操作:1.将x点到根的链全部修改成1颜色。

    2.将x点及其子树全部修改成0颜色。每次询问修改了多少个点的颜色。

    标程:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int N=400005;
     4 int cnt,head[N],q,size[N],Dfn,fa[N],in[N],out[N],top[N],x,n,sum[N],tag[N];
     5 char s[15];
     6 struct node{int to,next;}num[N];
     7 void add(int x,int y)
     8 {num[++cnt].to=y;num[cnt].next=head[x];head[x]=cnt;}
     9 void dfs(int x)
    10 {
    11     size[x]=1;
    12     for (int i=head[x];i;i=num[i].next)
    13       if (num[i].to!=fa[x])
    14       {
    15            dfs(num[i].to);
    16            size[x]+=size[num[i].to];
    17       }
    18 }
    19 void dfs1(int x)
    20 {
    21     in[x]=++Dfn;
    22     if (!top[x]) top[x]=x;
    23     int t=0;
    24     for (int i=head[x];i;i=num[i].next)
    25       if (num[i].to!=fa[x]&&size[num[i].to]>size[t]) t=num[i].to;
    26     if (t) top[t]=top[x],dfs1(t);
    27     for (int i=head[x];i;i=num[i].next)
    28       if (num[i].to!=fa[x]&&num[i].to!=t) dfs1(num[i].to);
    29     out[x]=Dfn;
    30 }
    31 void down(int k,int l,int r)
    32 {
    33     if (tag[k]==1)
    34     {
    35         tag[k<<1]=1;tag[k<<1|1]=1;
    36         sum[k<<1]=0;sum[k<<1|1]=0;
    37         tag[k]=0;
    38     }else
    39     if (tag[k]==2)
    40     {
    41         tag[k<<1]=2;tag[k<<1|1]=2;int mid=(l+r)>>1;
    42         sum[k<<1]=mid-l+1;sum[k<<1|1]=r-mid;
    43         tag[k]=0;
    44     }
    45 }
    46 int get_sum(int k,int l,int r,int L,int R,int op)
    47 {
    48     if (L<=l&&r<=R)
    49     {
    50         int t=sum[k];
    51         if (!op) {sum[k]=0;tag[k]=1;return t;}
    52         else {sum[k]=r-l+1;tag[k]=2;return (r-l+1)-t;}
    53     }
    54     int mid=(l+r)>>1,tmp=0;down(k,l,r);
    55     if (L<=mid) tmp+=get_sum(k<<1,l,mid,L,R,op);
    56     if (R>mid) tmp+=get_sum(k<<1|1,mid+1,r,L,R,op);
    57     sum[k]=sum[k<<1]+sum[k<<1|1];
    58     return tmp;
    59 }
    60 int qry(int x,int y)
    61 {
    62     int ans=0;
    63     for (;top[x]!=top[y];x=fa[top[x]])
    64     {
    65         if (in[x]<in[y]) swap(x,y);
    66         ans+=get_sum(1,1,n,in[top[x]],in[x],1);
    67     }
    68     if (in[x]>in[y]) swap(x,y);
    69     ans+=get_sum(1,1,n,in[x],in[y],1);
    70     return ans;
    71 }
    72 int main()
    73 {
    74     scanf("%d",&n);
    75     for (int i=2;i<=n;i++) scanf("%d",&fa[i]),add(++fa[i],i);
    76     dfs(1);dfs1(1);
    77     scanf("%d",&q);
    78     while (q--)
    79     {
    80         scanf("%s%d",s,&x);x++;
    81         if (s[0]=='i') printf("%d
    ",qry(1,x));
    82         else printf("%d
    ",get_sum(1,1,n,in[x],out[x],0));
    83     }
    84     return 0;
    85 } 

    易错点:1.注意标记会叠加,用一个标记数组,不要分两个。

    题解:树链剖分+线段树

    板子题吧。dfs序维护一下,再打个标记就好。

  • 相关阅读:
    编写规范
    Springboot自定义starter
    H5 新增标签
    vagrant virtualbox docker
    h5 sessionStorage localStorage
    mysql 出现You can't specify target table for update in FROM clause错误的解决方法
    linux下利用nohup后台运行jar文件包程序
    JVM内存分配 Xms128m Xmx512m XX:PermSize=128m XX:MaxPermSize=512m
    Spring Boot:内置tomcat启动和外部tomcat部署总结
    Mysql DELETE 不能使用别名? 是我不会用!
  • 原文地址:https://www.cnblogs.com/Scx117/p/8714955.html
Copyright © 2020-2023  润新知