zoukankan      html  css  js  c++  java
  • [Bzoj4196] [NOI2015] 软件包管理器 [树链剖分,线段树]

    题解摘要:树链剖分后用线段树区间查询修改,对于安装软件,将改点到根的路径全部变为1,对于卸载软件,将子树清空。注意边界,编号是从0开始的,容易漏掉树根。

    第一次写树剖~

      1 #include <iostream>
      2 #include <algorithm>
      3 #include <cstdio>
      4 #include <cstdlib>
      5 #include <cstring>
      6 #include <cmath>
      7 #include <ctime>
      8 
      9 using namespace std;
     10 
     11 struct Edge
     12 {
     13     int    to,next;
     14 }e[210000];
     15 
     16 int    ind,n,Pre[210000],f[810000],Sum[810000],Out_dfn[210000];
     17 int    p[210000],cnt,hv[210000],Head[210000],Dfn[210000];
     18 
     19 void    Add_edge(const int & x,const int & y)
     20 {
     21     e[++cnt].to=y;
     22     e[cnt].next=p[x];
     23     p[x]=cnt;
     24     return ;
     25 }
     26 
     27 int    Init_Dfs(const int& S)
     28 {
     29     int    num=1,i,Max_=0;
     30     for(i=p[S];i;i=e[i].next)
     31     {
     32         int temp=Init_Dfs(e[i].to);
     33         if(temp>Max_)Max_=temp,hv[S]=e[i].to;
     34         num+=temp;
     35     }
     36     return num;
     37 }
     38 
     39 void    Dfs(const int& S,const int& fa)
     40 {
     41     int    i;
     42     if(!Head[S])Head[S]=Head[fa];Dfn[S]=++ind;
     43     
     44     if(hv[S])Dfs(hv[S],S);
     45     for(i=p[S];i;i=e[i].next)
     46     {
     47         if(e[i].to!=hv[S])
     48         {
     49             Head[e[i].to]=e[i].to;
     50             Pre[e[i].to]=S;
     51             Dfs(e[i].to,S);
     52         }
     53     }
     54     Out_dfn[S]=ind;
     55     return ;
     56 }
     57 
     58 inline void    push_down(const int & num,const int & l,const int & r)
     59 {
     60     if(f[num])
     61     {
     62         if(l!=r)
     63         {
     64             f[num<<1]=f[num<<1|1]=f[num];
     65         }
     66         if(f[num]==1)Sum[num]=r-l+1;
     67         if(f[num]==-1)Sum[num]=0;
     68         f[num]=0;
     69     }
     70     return ;
     71 }
     72 
     73 void    push_up(const int & num,const int & l,const int & r)
     74 {
     75     if(l!=r)
     76     {
     77         int    mid=l+((r-l)>>1);
     78         push_down(num<<1,l,mid);
     79         push_down(num<<1|1,mid+1,r);
     80         Sum[num]=Sum[num<<1]+Sum[num<<1|1];
     81     }
     82     return ;
     83 }
     84 
     85 void    Change(const int & l,const int & r,const int & num,
     86         const int & s,const int & t,const int &d)
     87 {
     88     if(s<=l && r<=t)
     89     {
     90         f[num]=d;
     91         push_down(num,l,r);
     92         return ;
     93     }
     94     int    mid=l+((r-l)>>1);
     95     push_down(num,l,r);
     96     if(s<=mid)Change(l,mid,num<<1,s,t,d);
     97     if(t>mid) Change(mid+1,r,num<<1|1,s,t,d);
     98     push_up(num,l,r);
     99     return ;
    100 }
    101 
    102 int    Query(const int & l,const int & r,const int & num,
    103         const int & s,const int & t)
    104 {
    105     if(s<=l && r<=t)
    106     {
    107         push_down(num,l,r);
    108         return Sum[num];
    109     }
    110 
    111     int    mid=l+((r-l)>>1),temp=0;
    112     push_down(num,l,r);
    113     if(s<=mid)temp+=Query(l,mid,num<<1,s,t);
    114     if(t>mid) temp+=Query(mid+1,r,num<<1|1,s,t);
    115     push_up(num,l,r);
    116     return temp;
    117 }
    118 
    119 int    Get_sum_install(const int& S)
    120 {
    121     int    x=S,temp=0,sum=0;
    122     
    123     while(x)
    124     {
    125         sum+=Query(1,n,1,Dfn[Head[x]],Dfn[x]);
    126         Change(1,n,1,Dfn[Head[x]],Dfn[x],1);
    127         temp+=Dfn[x]-Dfn[Head[x]]+1;
    128         x=Pre[Head[x]];
    129     }
    130     
    131     return temp-sum;
    132 }
    133 
    134 int    Get_sum_remove(const int & S)
    135 {
    136     int    x=S,sum=0;
    137 
    138     sum=Query(1,n,1,Dfn[x],Out_dfn[x]);
    139     Change(1,n,1,Dfn[x],Out_dfn[x],-1);
    140 
    141     return sum;
    142 }
    143     
    144 int main()
    145 {
    146 
    147     int    i,x,q;
    148     char    op[15];
    149 
    150     scanf("%d",&n);
    151     for(i=2;i<=n;++i)
    152     {
    153         scanf("%d",&x);x++;
    154         Add_edge(x,i);
    155     }
    156 
    157     Init_Dfs(1);
    158 
    159     Head[1]=1;
    160     Dfs(1,1);
    161     scanf("%d",&q);
    162     for(i=1;i<=q;++i)
    163     {
    164         scanf("%s%d",op,&x);x++;
    165         if(op[0]=='i')
    166             printf("%d
    ",Get_sum_install(x));
    167         else
    168             printf("%d
    ",Get_sum_remove(x));
    169     }
    170 
    171     return 0;
    172 }
    View Code

    不知道为什么,BZOJ TLE了,但是UOJ AC(求大神指教)??

  • 相关阅读:
    [转]权限管理模型
    如何解决 “invalid resource directory name”, resource “crunch”
    Oracle ERP Interface堵住--Request Running too long time,查找Request执行的Sql
    【转】令人印象深刻的廣告詞
    【异常】SQL Server blocked access to STATEMENT OpenRowset/OpenDatasource
    你是喜欢一个人本身,还是
    关于Oracle 的安装记(不定期更新)
    kafka
    mysql去除换行和空格
    mysql 字段值拼接,同一字段循环拼接
  • 原文地址:https://www.cnblogs.com/Gster/p/4977886.html
Copyright © 2011-2022 走看看