zoukankan      html  css  js  c++  java
  • 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序维护一下,再打个标记就好。

  • 相关阅读:
    【数据结构】线性表&&顺序表详解和代码实例
    【智能算法】超详细的遗传算法(Genetic Algorithm)解析和TSP求解代码详解
    【智能算法】用模拟退火(SA, Simulated Annealing)算法解决旅行商问题 (TSP, Traveling Salesman Problem)
    【智能算法】迭代局部搜索(Iterated Local Search, ILS)详解
    10. js时间格式转换
    2. 解决svn working copy locked问题
    1. easyui tree 初始化的两种方式
    10. js截取最后一个斜杠后面的字符串
    2. apache整合tomcat部署集群
    1. apache如何启动
  • 原文地址:https://www.cnblogs.com/Scx117/p/8714955.html
Copyright © 2011-2022 走看看