zoukankan      html  css  js  c++  java
  • 【BZOJ 2243】染色

    传送门洛谷   BZOJ

    还不会LCT的小伙伴可以看一下这篇博客:LCT总结

    我初学动态树时就是看着那篇博客学的,写的很好!

    那好 言归正传。

    显然树上 x 到 y 的路径的问题都可以用LCT Access一下把路径剖离出来,那主要问题在于如何用Splay 来维护颜色呢?

    上图(XP 灵魂画手

    对于Splay树的每一个节点,维护四个信息

    c[x] : 节点本身的颜色

    cL[x]: 节点对应子树最左端的颜色

    cR[x]: 节点对应子树最右端的颜色

    tot[x]: 节点对应子树区间的颜色段数

    所以upDATA的时候就很显然啦~

     1 void pUP(int x){
     2     int lc=ch[x][0],rc=ch[x][1];
     3 
     4     cL[x]= lc? cL[lc]:c[x];
     5     cR[x]= rc? cR[rc]:c[x];
     6 
     7     if(lc && rc) tot[x]=tot[lc]+tot[rc]+1-(cR[lc]==c[x])-(cL[rc]==c[x]);
     8 
     9     if(lc &&!rc) tot[x]=tot[lc]+1-(cR[lc]==c[x]);
    10 
    11     if(!lc&& rc) tot[x]=tot[rc]+1-(cL[rc]==c[x]);
    12 
    13     if(!lc&&!rc) tot[x]=1;
    14 }

    其他部分就和平常的LCT没有什么区别了

    哦 对,pushDOWN时要注意 区间翻转,cL和cR要一起翻

    全代码~

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstdlib>
      4 #include<cstring>
      5 #include<algorithm>
      6 
      7 #define For(i,a,b) for(register int i=a;i<=b;++i)
      8 #define Dwn(i,a,b) for(register int i=a;i>=b;--i)
      9 #define Pn putchar('
    ')
     10 #define I inline 
     11 #define Re register
     12 
     13 using namespace std;
     14 
     15 const int N=1e5+5;
     16 
     17 int ch[N][2],fa[N],c[N],cL[N],cR[N],tot[N],tag[N],st[N],top,tgC[N];
     18 int n,m,x,y,z;
     19 char opt;
     20 
     21 I void read(int &v){
     22     v=0;
     23     char c=getchar();
     24     while(c<'0'||c>'9')c=getchar();
     25     while(c>='0'&&c<='9')v=v*10+c-'0',c=getchar();
     26 }
     27 void write(int x){
     28     if(x>9)write(x/10);
     29     int xx=x%10;
     30     putchar(xx+'0');
     31 }
     32 I bool NOrt(int x){
     33     return ch[fa[x]][1]==x || ch[fa[x]][0]==x;
     34 }
     35 I void pTAG(int x){
     36     swap(ch[x][0],ch[x][1]);
     37     swap(cL[x],cR[x]);
     38     tag[x]^=1;
     39 }
     40 I void pTGC(int x,int Col){
     41     c[x]=cL[x]=cR[x]=Col;
     42     tot[x]=1;
     43     tgC[x]=Col;
     44 }
     45 I void pDOWN(int x){
     46     if(tag[x]){
     47         if(ch[x][0])pTAG(ch[x][0]);
     48         if(ch[x][1])pTAG(ch[x][1]);
     49         tag[x]^=1;
     50     }
     51     if(tgC[x]){
     52         if(ch[x][0])pTGC(ch[x][0],tgC[x]);
     53         if(ch[x][1])pTGC(ch[x][1],tgC[x]);
     54         tgC[x]=0;
     55     }
     56 }
     57 I void pUP(int x){
     58     int lc=ch[x][0],rc=ch[x][1];
     59     
     60     cL[x]= lc? cL[lc]:c[x];
     61     cR[x]= rc? cR[rc]:c[x];
     62     
     63     if(lc && rc) tot[x]=tot[lc]+tot[rc]+1-(cR[lc]==c[x])-(cL[rc]==c[x]);
     64     
     65     if(lc &&!rc) tot[x]=tot[lc]+1-(cR[lc]==c[x]);
     66     
     67     if(!lc&& rc) tot[x]=tot[rc]+1-(cL[rc]==c[x]);
     68     
     69     if(!lc&&!rc) tot[x]=1;
     70 }
     71 I bool Wson(int x){
     72     return ch[fa[x]][1]==x;
     73 }
     74 I void Rotate(int x){
     75     int y=fa[x];
     76     int z=fa[y];
     77     int ws=Wson(x);
     78     if(NOrt(y))ch[z][Wson(y)]=x;
     79     fa[x]=z;
     80     
     81     ch[y][ws]=ch[x][ws^1];
     82     if(ch[x][ws^1])fa[ch[x][ws^1]]=y;
     83     
     84     ch[x][ws^1]=y;
     85     fa[y]=x;
     86     
     87     pUP(y); pUP(x);
     88 }
     89 I void Splay(int x){
     90     top=0; int now=x;
     91     st[++top]=now;
     92     while(NOrt(now))st[++top]=now=fa[now];
     93     while(top) pDOWN(st[top--]);
     94     
     95     while(NOrt(x)){
     96         int y=fa[x];
     97         if(NOrt(y)){
     98             if(Wson(y)==Wson(x))Rotate(y);
     99             else Rotate(x);
    100         }
    101         Rotate(x);
    102     }
    103 }
    104 I void Access(int x){
    105     int lst=0;
    106     while(x){
    107         Splay(x); ch[x][1]=lst; pUP(x);
    108         lst=x; x=fa[x];
    109     }
    110 }
    111 I void ChangeRt(int x){
    112     Access(x); Splay(x); pTAG(x);
    113 }
    114 I void Link(int x,int y){
    115     ChangeRt(x); fa[x]=y;
    116 }
    117 I void Split(int x,int y){
    118     ChangeRt(x); Access(y); Splay(y);
    119 }
    120 int main(){ 
    121     read(n); read(m); 
    122     For(i,1,n){
    123         read(c[i]); tot[i]=1;
    124         cL[i]=cR[i]=c[i]; 
    125     };
    126     For(i,1,n-1){ 
    127         read(x); read(y);
    128         Link(x,y);
    129     }
    130     For(i,1,m){ 
    131         opt=getchar();
    132         while(opt!='C'&&opt!='Q')opt=getchar();
    133         if(opt=='C'){
    134             read(x); read(y); read(z);
    135             Split(x,y); pTGC(y,z);
    136         }
    137         if(opt=='Q'){
    138             read(x); read(y);
    139             Split(x,y);
    140             write(tot[y]); Pn;
    141         }
    142     }
    143     return 0;
    144 }
  • 相关阅读:
    pair和map
    lower_bound( )和upper_bound( )
    P1886 滑动窗口 /【模板】单调队列
    数的度(数位dp)
    最小生成树
    刷题-力扣-1052. 爱生气的书店老板
    刷题-力扣-766. 托普利茨矩阵
    刷题-力扣-28. 实现 strStr()
    刷题-力扣-697. 数组的度
    刷题-力扣-1004. 最大连续1的个数 III
  • 原文地址:https://www.cnblogs.com/HLAUV/p/10330934.html
Copyright © 2011-2022 走看看