zoukankan      html  css  js  c++  java
  • 【树链剖分】bzoj2243 [SDOI2011]染色

    树链剖分模板题。线段树维护每个段中的颜色数、左端点颜色、右端点颜色。

    pushup: col[rt]=col[rt<<1]+col[rt<<1|1]-(Rcol[rt<<1]==Lcol[rt<<1|1]);
    在合并各个链的答案时,要注意若两头颜色相同,ans--。
    【教训:树链剖分题在进行建立线段树树时,要注意下面代码中的标注部分。否则会WA】
    Code:
      1 #include<cstdio>
      2 #include<algorithm>
      3 using namespace std;
      4 #define lson rt<<1,l,m
      5 #define rson rt<<1|1,m+1,r
      6 #define maxn 100001
      7 int col[maxn<<2],L[maxn<<2],R[maxn<<2],delta[maxn<<2],n,m,Val[maxn],Num[maxn];
      8 int V[maxn<<1],First[maxn<<1],Next[maxn<<1],All_Lcol,All_Rcol,en;
      9 bool vis[maxn];
     10 int top[maxn],son[maxn],tot,dep[maxn],fa[maxn],siz[maxn],Map[maxn];
     11 inline void AddEdge(const int &UU,const int &VV){V[++en]=VV;Next[en]=First[UU];First[UU]=en;}
     12 inline void pushup(const int &rt)
     13 {
     14     L[rt]=L[rt<<1];
     15     R[rt]=R[rt<<1|1];
     16     col[rt]=col[rt<<1]+col[rt<<1|1]-(R[rt<<1]==L[rt<<1|1]);
     17 }
     18 inline void pushdown(const int &rt)
     19 {
     20     if(delta[rt]!=-1)
     21       {
     22           L[rt<<1]=R[rt<<1]=L[rt<<1|1]=R[rt<<1|1]=delta[rt];
     23           delta[rt<<1]=delta[rt<<1|1]=delta[rt];
     24           delta[rt]=-1;
     25           col[rt<<1]=col[rt<<1|1]=1;
     26       }
     27 }
     28 void buildtree(int rt,int l,int r)
     29 {
     30     delta[rt]=-1;
     31     if(l==r)
     32       {
     33           col[rt]=1;
     34           L[rt]=R[rt]=Val[Map[l]];//l是线段树中的新位置,
     35                                 //Map[l]表示新位置对应的在树中的编号是谁 
     36         return;
     37       }
     38     int m=l+r>>1;
     39     buildtree(lson);
     40     buildtree(rson);
     41     pushup(rt);
     42 }
     43 void update(int ql,int qr,int v,int rt,int l,int r)
     44 {
     45     if(ql<=l&&r<=qr)
     46       {
     47         delta[rt]=L[rt]=R[rt]=v;//更新当前结点的标记值 
     48         col[rt]=1;
     49         return;
     50       }
     51     pushdown(rt);//将该节点的标记下传到孩子们 
     52     int m=l+r>>1;
     53     if(ql<=m)
     54       update(ql,qr,v,lson);
     55     if(m<qr)
     56       update(ql,qr,v,rson);
     57     pushup(rt);
     58 }
     59 int query(int ql,int qr,int rt,int l,int r)
     60 {
     61     if(ql==l)
     62       All_Lcol=L[rt];
     63     if(r==qr)
     64       All_Rcol=R[rt];
     65     if(ql<=l&&r<=qr)
     66       return col[rt];
     67     pushdown(rt);//将该节点的标记下传到孩子们 
     68     int m=l+r>>1,res=0,now1=-1,now2=-1;
     69     if(ql<=m)
     70       {
     71           res+=query(ql,qr,lson);
     72           now1=R[rt<<1];
     73       }
     74     if(m<qr)
     75       {
     76           res+=query(ql,qr,rson);
     77           now2=L[rt<<1|1];
     78       }
     79     res-=(now1==now2 && now1!=-1);
     80     return res;
     81 }
     82 inline void Update(int u,int v,int val)
     83 {
     84     int f1=top[u],f2=top[v];
     85     while(f1!=f2)
     86       {
     87           if(dep[f1]<dep[f2])
     88             {
     89                 swap(u,v);
     90                 swap(f1,f2);
     91             }
     92           update(Num[f1],Num[u],val,1,1,n);
     93           u=fa[f1];
     94           f1=top[u];
     95       }
     96     if(dep[u]<dep[v])
     97       swap(u,v);
     98     update(Num[v],Num[u],val,1,1,n);
     99 }
    100 inline int Query(int u,int v)
    101 {
    102     int f1=top[u],f2=top[v],ans=0,t1=-1,t2=-1;
    103     while(f1!=f2)
    104       {
    105           if(dep[f1]<dep[f2])
    106             {
    107                 swap(u,v);
    108                 swap(f1,f2);
    109                 swap(t1,t2);
    110             }
    111           ans+=query(Num[f1],Num[u],1,1,n);
    112           ans-=(t1==All_Rcol);
    113           t1=All_Lcol;
    114           u=fa[f1];
    115           f1=top[u];
    116       }
    117     if(dep[u]<dep[v])
    118       {
    119           swap(u,v);
    120           swap(t1,t2);
    121       }
    122     ans+=query(Num[v],Num[u],1,1,n);
    123     ans-=((t1==All_Rcol&&t1!=-1)+(t2==All_Lcol&&t2!=-1));
    124     return ans;
    125 }
    126 void dfs1(int cur,int father,int depth)
    127 {
    128     fa[cur]=father;
    129     dep[cur]=depth;
    130     siz[cur]=1;
    131     for(int i=First[cur];i;i=Next[i])
    132       if(!vis[V[i]])
    133         {
    134           vis[V[i]]=true;
    135           dfs1(V[i],cur,depth+1);
    136           siz[cur]+=siz[V[i]];
    137           if(siz[V[i]]>siz[son[cur]])
    138             son[cur]=V[i];
    139           vis[V[i]]=false;
    140         }
    141 }
    142 void dfs2(int cur)
    143 {
    144     if(son[cur]&&!vis[son[cur]])
    145       {
    146           vis[son[cur]]=true;
    147           top[son[cur]]=top[cur];
    148           Num[son[cur]]=++tot;
    149           Map[tot]=son[cur];
    150           dfs2(son[cur]);
    151           vis[son[cur]]=false;
    152       }
    153     for(int i=First[cur];i;i=Next[i])
    154       if(son[cur]!=V[i]&&!vis[V[i]])
    155         {
    156           vis[V[i]]=true;
    157           top[V[i]]=V[i];
    158           Num[V[i]]=++tot;
    159           Map[tot]=V[i];
    160           dfs2(V[i]);
    161           vis[V[i]]=false;
    162         }
    163 }
    164 int Res,num;
    165 char C;
    166 char CH[20];
    167 inline int getint()
    168 {
    169     Res=0;
    170     C='*'; 
    171     while(C<'0'||C>'9')
    172       C=getchar();
    173     while(C>='0'&&C<='9')
    174       {
    175         Res=Res*10+(C-'0');
    176         C=getchar();
    177       }
    178     return Res;
    179 }
    180 inline void putint(int x)
    181 {
    182     num=0;  
    183     while(x>0)
    184       CH[++num]=x%10,x/=10;
    185     while(num)   
    186       putchar(CH[num--]+48);
    187     putchar('
    ');
    188 }
    189 int main()
    190 {
    191     int x,y,a,b,c;
    192     char op;
    193     n=getint();
    194     m=getint();
    195     for(int i=1;i<=n;i++)
    196       Val[i]=getint();
    197     for(int i=1;i<n;i++){x=getint();y=getint();AddEdge(x,y);AddEdge(y,x);}
    198     top[1]=1;
    199     Num[1]=++tot;
    200     Map[tot]=1;
    201     vis[1]=true;
    202     dfs1(1,0,1);
    203     dfs2(1);
    204     buildtree(1,1,n);
    205     for(int i=1;i<=m;i++)
    206       {
    207           getchar();
    208           op=getchar();
    209           a=getint();
    210           b=getint();
    211           if(op=='C')
    212             {
    213                 c=getint();
    214                 Update(a,b,c);
    215             }
    216           else
    217             putint(Query(a,b));
    218       }
    219     return 0;
    220 }
    ——The Solution By AutSky_JadeK From UESTC 转载请注明出处:http://www.cnblogs.com/autsky-jadek/
  • 相关阅读:
    viso图插入Word中大片空白解决办法
    面向对象设计模式中的单例模式和工厂模式
    面向对象知识整理
    require和include的区别及自动加载的定义
    面向对象的三大特性及定义
    重写和重载的区别 (部分内容转自竹木人)
    面向对象的基本概念
    PHP json_encode( ) 函数介绍
    js页面跳转常用的几种方式
    js中页面刷新和页面跳转的方法总结 [ 转自欢醉同学 ]
  • 原文地址:https://www.cnblogs.com/autsky-jadek/p/3959460.html
Copyright © 2011-2022 走看看