zoukankan      html  css  js  c++  java
  • BZOJ

    同样是可以用LCT解决的树剖问题之一。

    注意反转的时候要考虑对左右端点颜色的影响,而且要先反转再打标记(这点不知道为啥)

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const int N=1e5+10;
     5 int n,m,a[N],col[N][2],fa[N],ch[N][2],sum[N],flp[N],sta[N],tp,lz[N];
     6 #define ls(u) ch[u][0]
     7 #define rs(u) ch[u][1]
     8 int sf(int u) {return u==rs(fa[u]);}
     9 bool isrt(int u) {return u!=ls(fa[u])&&u!=rs(fa[u]);}
    10 void pu(int u) {
    11     sum[u]=1,col[u][0]=col[u][1]=a[u];
    12     for(int f=0; f<2; ++f)if(ch[u][f]) {
    13             sum[u]+=sum[ch[u][f]];
    14             col[u][f]=col[ch[u][f]][f];
    15             if(col[ch[u][f]][f^1]==a[u])--sum[u];
    16         }
    17 }
    18 void change(int u,int x) {if(u)a[u]=col[u][0]=col[u][1]=lz[u]=x,sum[u]=1;}
    19 void rev(int u) {flp[u]^=1,swap(ls(u),rs(u)),swap(col[u][0],col[u][1]);}
    20 void pd(int u) {
    21     if(flp[u])rev(ls(u)),rev(rs(u)),flp[u]=0;;
    22     if(~lz[u])change(ls(u),lz[u]),change(rs(u),lz[u]),lz[u]=-1;
    23 }
    24 void rot(int u) {
    25     int v=fa[u],f=sf(u);
    26     if(!isrt(v))ch[fa[v]][sf(v)]=u;
    27     ch[v][f]=ch[u][f^1],fa[ch[v][f]]=v;
    28     fa[u]=fa[v],ch[u][f^1]=v,fa[v]=u,pu(v);
    29 }
    30 void splay(int u) {
    31     sta[tp=0]=u;
    32     for(int v=u; !isrt(v); v=fa[v])sta[++tp]=fa[v];
    33     for(; ~tp; pd(sta[tp--]));
    34     for(; !isrt(u); rot(u))if(!isrt(fa[u])&&sf(fa[u])==sf(u))rot(fa[u]);
    35     pu(u);
    36 }
    37 void access(int u) {for(int v=0; u; splay(u),rs(u)=v,pu(u),u=fa[v=u]);}
    38 void makert(int u) {access(u),splay(u),rev(u);}
    39 void link(int u,int v) {makert(u),fa[u]=v;}
    40 void split(int u,int v) {makert(u),access(v),splay(v);}
    41 int main() {
    42     scanf("%d%d",&n,&m);
    43     for(int i=1; i<=n; ++i)scanf("%d",&a[i]),lz[i]=-1,pu(i);
    44     for(int i=1; i<n; ++i) {
    45         int u,v;
    46         scanf("%d%d",&u,&v);
    47         link(u,v);
    48     }
    49     while(m--) {
    50         char ch;
    51         int x,y,z;
    52         scanf(" %c%d%d",&ch,&x,&y);
    53         if(ch=='C')scanf("%d",&z),split(x,y),change(y,z);
    54         else split(x,y),printf("%d
    ",sum[y]);
    55     }
    56     return 0;
    57 }
  • 相关阅读:
    windows和linux下安装 redis
    YII1 配置redis并使用
    YII1 安装smarty模版引擎
    thinkphp5 阿里云短信 发送多参数的短信
    利用securecrt或者xshell 下载服务器端文件到本地windows系统中
    Swift 内存管理
    扩展和协议
    继承
    构造与析构
    方法
  • 原文地址:https://www.cnblogs.com/asdfsag/p/11077830.html
Copyright © 2011-2022 走看看