[SDOI2011]染色

题目描述

输入输出格式



输出格式:

对于每个询问操作,输出一行答案。

解法

ps:这题本来是树剖的,但我用lct写的,以下是lct的写法,树剖会有所不同

我们考虑把连接不同色点的边权值设为1,连接同色的点的边权设为0,这样我们就可以把问题转化为查询这条路径上所有的边权和,你要输出的就是这个答案加一。

对于维护,我们对每条路径维护一个最左端点的值和最右端点的值,这样就可以统计O(1)地合并信息,修改时做一个懒标记,下放时将当前ans清零再修改左右端点即可。

区间反转时左右端点也要反转

区间反转时左右端点也要反转

区间反转时左右端点也要反转

重要的话说三遍(我就被坑了好久)。

代码

#include<bits/stdc++.h>
#define rg register
using namespace std;
int gi(){
char a=getchar();int b=0;
while(a<'0'||a>'9')a=getchar();
while(a>='0'&&a<='9')b=b*10+a-'0',a=getchar();
return b;
}
const int N=1e6;
int fa[N],ch[N][2],ans[N],w[N],l[N],r[N],lazy1[N],lazy2[N],fz[N],top;
int get(int x){return ch[fa[x]][1]==x;}
int isroot(int x){return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;}
void pushdown(int x){
rg int L=ch[x][0],R=ch[x][1];
if(lazy1[x]){
swap(ch[x][0],ch[x][1]);
swap(l[L],r[L]);
swap(l[R],r[R]);
lazy1[L]^=1;
lazy1[R]^=1;
lazy1[x]^=1;
}
if(lazy2[x]){
w[x]=l[x]=r[x]=lazy2[L]=lazy2[R]=lazy2[x];
lazy2[x]=0;
ans[x]=0;
}
}
void pushup(int x){
pushdown(ch[x][0]);
pushdown(ch[x][1]);
ans[x]=0;
if(ch[x][0]){
l[x]=l[ch[x][0]];
if(w[x]!=r[ch[x][0]])ans[x]++;
}
else l[x]=w[x];
if(ch[x][1]){
r[x]=r[ch[x][1]];
if(w[x]!=l[ch[x][1]])ans[x]++;
}
else r[x]=w[x];
ans[x]+=ans[ch[x][0]]+ans[ch[x][1]];
}
void rotate(int x){
int y=fa[x],z=fa[y],k=get(x);
fa[x]=z;if(!isroot(y))ch[z][ch[z][1]==y]=x;
ch[y][k]=ch[x][k^1];fa[ch[y][k]]=y;
fa[y]=x;ch[x][k^1]=y;
pushup(y);pushup(x);
}
void splay(int x){
for(int i=x;;i=fa[i]){
fz[++top]=i;
if(isroot(i))break;
}
while(top){pushdown(fz[top--]);}
while(!isroot(x)){
int y=fa[x];
if(!isroot(y))
if(get(x)==get(y))rotate(y);
else rotate(x);
rotate(x);
}
}
void access(int x){for(int y=0;x;y=x,x=fa[x])splay(x),ch[x][1]=y,pushup(x);}
void makeroot(int x){access(x);splay(x);lazy1[x]^=1;}
void link(int x,int y){makeroot(x);fa[x]=y;}
void split(int x,int y){makeroot(x);access(y);splay(y);}
void update(int x,int y,int k){split(x,y);lazy2[y]=k;}
void query(int x,int y){split(x,y);printf("%d\n",ans[y]+1);}
int main(){
int n=gi(),m=gi();
for(int i=1;i<=n;++i){
w[i]=gi();
l[i]=r[i]=w[i];
}
for(int i=1;i<n;++i){
int x=gi(),y=gi();
link(x,y);
}
while(m--){
char op=getchar();
while(op!='C'&&op!='Q')op=getchar();
if(op=='C'){
int x=gi(),y=gi(),k=gi();
update(x,y,k);
}
if(op=='Q'){
int x=gi(),y=gi();
query(x,y);
}
}
return 0;
}

[SDOI2011]染色的更多相关文章

  1. BZOJ 2243: [SDOI2011]染色 [树链剖分]

    2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 6651  Solved: 2432[Submit][Status ...

  2. bzoj-2243 2243: [SDOI2011]染色(树链剖分)

    题目链接: 2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 6267  Solved: 2291 Descript ...

  3. 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树

    [BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...

  4. bzoj2243:[SDOI2011]染色

    链剖就可以了.一开始的想法错了.但也非常接近了.妈呀调的要死...然后把字体再缩小一号查错起来比较容易QAQ. #include<cstdio> #include<cstring&g ...

  5. bzoj 2243 [SDOI2011]染色(树链剖分,线段树)

    2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 4637  Solved: 1726[Submit][Status ...

  6. Bzoj 2243: [SDOI2011]染色 树链剖分,LCT,动态树

    2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 5020  Solved: 1872[Submit][Status ...

  7. 2243: [SDOI2011]染色

    2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 3113  Solved: 1204[Submit][Status ...

  8. bzoj 2243 [SDOI2011]染色(树链剖分+线段树合并)

    [bzoj2243][SDOI2011]染色 2017年10月20日 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询 ...

  9. bzoj2243[SDOI2011]染色 树链剖分+线段树

    2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 9012  Solved: 3375[Submit][Status ...

随机推荐

  1. Flex中的FusionCharts 2D柱形图

    1.2D柱形图源码 <?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:f ...

  2. 你的变量究竟存储在什么地方 && 全局内存

    我相信大家都有过这样的经历,在面试过程中,考官通常会给你一道题目,然后问你某个变量存储在什么地方,在内存中是如何存储的等等一系列问题.不仅仅是在面试中,学校里面的考试也会碰到同样的问题.  如果你还不 ...

  3. CF368 E - Garlands

    主席树 其实暴力二维树状还更快 #include<bits/stdc++.h> using namespace std; typedef long long ll; const int M ...

  4. 加深try catch Finnly的理解

    上代码 public String twoGetFeeInfoByWithUnit(JSONArray jsonArray,String key1,String key2){ String Debit ...

  5. Echarts自动刷新数据

    1.Echarts自动刷新数据 1.Echarts柱状图的正常配置 注:声明了 myChart.test这两个都有用 官方示例中myChart是声明在 function(ec)里面的 <scri ...

  6. 【BZOJ2342】双倍回文(回文树)

    [BZOJ2342]双倍回文(回文树) 题面 BZOJ 题解 构建出回文树之后 在\(fail\)树上进行\(dp\) 如果一个点代表的回文串长度为\(4\)的倍数 并且存在长度为它的一半的回文后缀 ...

  7. LightOJ1259 Goldbach`s Conjecture

    题面 T组询问,每组询问是一个偶数n 验证哥德巴赫猜想 回答n=a+b 且a,b(a<=b)是质数的方案个数 Input Input starts with an integer T (≤ 30 ...

  8. 分享一下我进入IT行业的经历

    今天突然根想写博客,就注册了一个,分享一下我的成长经历. 我第一次接触编程的时候是在上大学的时候,我学的专业是工程测量接触的第一个语言是vb,我记得很清楚,我当时写出第一个小Demo是的心情,感觉到了 ...

  9. Django中下划线的用法介绍(一)

    在Django中有相当多的操作是通过双下划线与动作连接起来使用,为了以后更加方便的查找和使用,现在总结以下Django中基本的双下划线操作 比较符:大于--gt  小于--lt 等于--eq  大于等 ...

  10. sharepoint 2013实践

    之前在一篇文章中说过了SharePoint环境的安装.那么如何使用SharePoint开发一个站点呢?这就是本篇所要阐述的问题. 在如何具体操作之前,我们先来普及下SharePoint基础知识.Far ...