博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[SDOI2011]染色
阅读量:5946 次
发布时间:2019-06-19

本文共 2334 字,大约阅读时间需要 7 分钟。

[SDOI2011]染色

题目描述

o_1600.png

输入输出格式

o_1601.png

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

解法

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

我们考虑把连接不同色点的边权值设为1,连接同色的点的边权设为0,这样我们就可以把问题转化为查询这条路径上所有的边权和,你要输出的就是这个答案加一。
对于维护,我们对每条路径维护一个最左端点的值和最右端点的值,这样就可以统计O(1)地合并信息,修改时做一个懒标记,下放时将当前ans清零再修改左右端点即可。
区间反转时左右端点也要反转
区间反转时左右端点也要反转
区间反转时左右端点也要反转
重要的话说三遍(我就被坑了好久)。

代码

#include
#define rg registerusing 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

转载于:https://www.cnblogs.com/ljq-despair/p/8654083.html

你可能感兴趣的文章
免费微信公众号专用h5在线电影票API
查看>>
专访刘刚:360手机卫士的性能监控与优化
查看>>
FB正在大规模重构React Native,预计今年发布
查看>>
从0到1:腾讯Yoo视频底层页推荐系统实践
查看>>
推荐10个CI/CD工具,用于云平台集成交付
查看>>
云平台宕机引发的系列思考,企业如何自救?
查看>>
Java EE跟JCP说再见
查看>>
整洁代码之道——重构
查看>>
Oracle加入CNCF,发布Kubernetes on Oracle Linux以及Terraform Kubernetes Cloud Installer
查看>>
Scrum指南更新:Ken Schwaber、Jeff Sutherland访谈
查看>>
在瑞士最大银行驱动创新
查看>>
CRI Shimv2:一种 Kubernetes 集成容器运行时的新思路
查看>>
机器人操作系统来到Windows
查看>>
通过规模化Scrum创造最新技术的打印机
查看>>
时序数据库DolphinDB和TimescaleDB 性能对比测试报告
查看>>
准备好了?测试人员迟早会被要求测试包含区块链技术的解决方案
查看>>
用户故事 | 刷算法面试题的4种思考方式
查看>>
Visual Studio 2017 15.9 Previews扩展C++调试功能
查看>>
宜人贷CTO段念:透明与面向目标是管理理念的核心
查看>>
理解HTTPS
查看>>