可爱的树链剖分(染色)
可爱的树链剖分(染色)
这道题 就是 一道 普通的! 树链剖分+线段树覆盖
注意一下两个线段树合并的时候 如果 lval(node<<1∣1)==rval(node<<1)lval(node<<1|1)==rval(node<<1)lval(node<<1∣1)==rval(node<<1) 相当于这两个线段树的相邻的数字数相同的 那么合并时的tottottot sumsumsum 应该 –
所以说这道题有什么细节吗 我感觉是没有的 然而我调了一下午+晚上两个小时 (再次感谢人帅心善的kma小哥哥) (话说为什么他有这么多女朋友,而我还是单身呢) 不 我有萌德
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#define int long long
using namespace std;
const int maxn=1e6+10;
int read(){int x=0,f=1;char ch=getchar();while(ch<'0' || ch>'9'){if(ch=='-') f=-1;ch=getchar();}while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();};return x*f;
}
int n,m,color[maxn],fir[maxn<<1],nxt[maxn<<1],to[maxn<<1],tot,top[maxn];
int size[maxn],son[maxn],fa[maxn],rk[maxn],id[maxn],dep[maxn],times;
char op[3];
struct nodee{int l,r,lval,rval,sum,tag;#define lval(x) tree[x].lval#define rval(x) tree[x].rval#define l(x) tree[x].l#define r(x) tree[x].r#define sum(x) tree[x].sum#define tag(x) tree[x].tag
}tree[maxn<<4];
void add(int x,int y){nxt[++tot]=fir[x];fir[x]=tot;to[tot]=y;}
void dfs1(int x){dep[x]=dep[fa[x]]+1;size[x]=1;for(int i=fir[x];i;i=nxt[i]){int y=to[i];if(y==fa[x]) continue;fa[y]=x;dfs1(y);size[x]+=size[y];if(size[son[x]]<size[y]) son[x]=y;}
}
void dfs2(int x,int tp){top[x]=tp;id[x]=++times;rk[times]=x;if(son[x]) dfs2(son[x],tp);for(int i=fir[x];i;i=nxt[i]){int y=to[i];if(id[y]) continue;dfs2(y,y);}
}
void push_up(int node){lval(node)=lval(node<<1);rval(node)=rval(node<<1|1);sum(node)=sum(node<<1)+sum(node<<1|1);if(rval(node<<1)==lval(node<<1|1)) --sum(node);
}
void build(int node,int l,int r){l(node)=l;r(node)=r;if(l==r){lval(node)=rval(node)=color[rk[l]];sum(node)=1;return ;}int mid=l+r>>1;build(node<<1,l,mid);build(node<<1|1,mid+1,r);push_up(node);
}
void push_down(int node){if(tag(node)){tag(node<<1)=tag(node<<1|1)=tag(node);lval(node<<1)=rval(node<<1)=lval(node<<1|1)=rval(node<<1|1)=tag(node);sum(node<<1)=sum(node<<1|1)=1;tag(node)=0;}
}
void modify(int node,int ql,int qr,int z){if(ql<=l(node) && r(node)<=qr){sum(node)=1;tag(node)=z;lval(node)=z;rval(node)=z;return ;}push_down(node);int mid=l(node)+r(node)>>1;if(ql<=mid) modify(node<<1,ql,qr,z);if(mid<qr) modify(node<<1|1,ql,qr,z);push_up(node);
}
void chain_modify(int x,int y,int z){while(top[x]!=top[y]){if(dep[top[x]]<dep[top[y]]){x^=y^=x^=y;}modify(1,id[top[x]],id[x],z);x=fa[top[x]];}if(dep[x]<dep[y]) x^=y^=x^=y;modify(1,id[y],id[x],z);return ;
}
int Rval = 0,Lval = 0,last1 = 0,last2 = 0;
int query(int node,int ql,int qr){if(ql==l(node)) Lval=lval(node);if(qr==r(node)) Rval=rval(node);if(ql<=l(node) && r(node)<=qr){return sum(node);}push_down(node);int ans=0,mid=l(node)+r(node)>>1;if(ql>mid) ans+=query(node<<1|1,ql,qr);else if (qr <= mid) ans += query(node<<1,ql,qr);else {if(rval(node<<1)==lval(node<<1|1)) ans+=query(node<<1,ql,qr)+query(node<<1|1,ql,qr)-1;else ans+=query(node<<1,ql,qr)+query(node<<1|1,ql,qr);}return ans;
}
int chain_query(int x,int y){last1 = 0, last2 = 0, Lval = 0, Rval = 0;int tx=top[x],ty=top[y];int ans=0;while(tx!=ty){if(dep[tx]<dep[ty]){x^=y^=x^=y;tx^=ty^=tx^=ty;last1^=last2^=last1^=last2;}ans+=query(1,id[tx],id[x]);if(last1==Rval) --ans;last1=Lval;x=fa[tx];tx=top[x];}if(dep[x]<dep[y]){x^=y^=x^=y;last1^=last2^=last1^=last2;}ans+=query(1,id[y],id[x]);if(Rval==last1) ans--;if(Lval==last2) ans--;return ans;
}
signed main(){n=read();m=read();for(int i=1;i<=n;i++)color[i]=read();for(int i=1,x,y;i<=n-1;i++){x=read();y=read();add(x,y);add(y,x);}dfs1(1);dfs2(1,1);build(1,1,n);for(int i=1,x,y,z;i<=m;i++){scanf("%s",op + 1);x=read();y=read();if(op[1]=='C') {z=read();chain_modify(x,y,z);}if(op[1]=='Q') printf("%lld\n",chain_query(x,y));}return 0;
}
但是注意一下 在chain_query 和 chain_modify 的时候 最后的判断语句一定不能改方向(为什么呢我不知道) 我好难受啊
可爱的树链剖分(染色)相关推荐
- [树链剖分][SDOI 2011]染色,Housewife Wind
文章目录 T1:Housewife Wind 题目 题解 code T2:染色 题目 题解 code 今天选择写这篇博客主要是为了告诉大家一个道理,数组比vectorvectorvector快太多了, ...
- BZOJ 2243 染色(树链剖分好题)
2243: [SDOI2011]染色 Time Limit: 20 Sec Memory Limit: 512 MB Submit: 7971 Solved: 2990 [Submit][Stat ...
- 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树
[BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...
- 【YBT2022寒假Day8 A】染色计划(Tarjan)(线段树优化建边)(树链剖分)
染色计划 题目链接:YBT2022寒假Day8 A 题目大意 给你一棵树,然后有 k 中颜色,每个点有一个颜色,然后问你要修改多少次,才能使得一个存在的颜色的所有点构成一个连通块. 一个修改操作指选择 ...
- 树链剖分——线段树区间合并bzoj染色
线段树区间合并就挺麻烦了,再套个树链就更加鬼畜,不过除了代码量大就没什么其他的了.. 一些细节:线段树每个结点用结构体保存,pushup等合并函数改成返回一个结构体,这样好写一些 struct Seg ...
- P2486 [SDOI2011]染色(树链剖分+线段树)
题干描述 输入描述 输出格式 对于每个询问操作,输出一行答案. 输入输出样例 输入 #1 复制 6 5 2 2 1 2 1 1 1 2 1 3 2 4 2 5 2 6 Q 3 5 C 2 1 1 Q ...
- 【树链剖分】染色(luogu 2486/金牌导航 树链剖分-3)
正题 luogu 2486 金牌导航 树链剖分-3 题目大意 给你一棵树,让你进行以下操作: 1.把一条路径染上一个颜色 2.查询一条路径上有多少个颜色段 解题思路 用树链剖分把问题转化为链上问题 然 ...
- 【BZOJ2243】【codevs1566】染色,树链剖分练习
传送门1 传送门2 写在前面:比一些裸题好多了-- 思路:典型的树链剖分,不过我们要存储的是每段区间内颜色段数量,对于这个问题,显然我们要存下整个区间的详细状态是不可能的,但可以把这个区间的左右端点记 ...
- 洛谷P2486 [SDOI2011]染色(树链剖分+线段树判断边界)
[题目链接] [思路]: 涉及到树上区间修改操作,所以使用树链剖分,涉及到区间查询,所以使用线段树. update操作时,就正常操作,难点在于query操作的计数. 因为树链剖分的dfs序只能保证一条 ...
最新文章
- Intel Realsense D435 将深度图的灰度图映射为彩色图,打印输出灰度图或彩色图
- boost::fibers模块实现适配方法调用的测试程序
- DisplayPowerState
- HttpURLConnection和HttpClient的简单用法
- Tips--TensorFlow报错:tensorflow:Early stopping conditioned on metric `val_loss` which is not available
- 北师大版图形的旋转二教案_新北师大版八年级下册数学 《图形的旋转(2)》教案...
- Atitit alldiaryindex v1 t717 目录 1. Fix	1 2. Diary detail	1 2.1. Diary 1987---2016.12	1 2.2. Diary20
- 国际冠码与国际电话区号
- 关于 移动硬盘数据丢失问题 的解决方法
- CAD修复块中心点(网页版)
- 小记!华为 8.0系统切换APP内语言(中英文)无效(其他版本手机均有效)。
- matlab multiply,MATLAB Matrix Multiply Code效率
- UVM:一个简易验证平台例子
- 微信 SHA1 签名_微信公众号自动回复功能开发
- R语言实战学习--回归
- iOS通过dSYM文件分析crash
- cmd的一些有趣命令
- sql查询今天,近七天,近一个月,近一年的数量统计
- 深入浅出WPF知识点汇总一
- 数据结构: 中序非递归遍历二叉树
热门文章
- java网课|static
- 解析USGS网站页面中的地震空间数据
- Dynamic Movement Primitives与UR5机械臂仿真
- 阿里P10赵海平跳槽字节跳动:深度解析跳槽从开始到结束完整流程!
- django实训报告
- 制作服装推广软文html,服装行业软文怎么写,公众号服装分销软文推广!
- java如何编写spi接口_软件模拟SPI接口程序代码(4种模式)
- 【JS】隐匿在计算机软硬件背后的语言
- 文笔很差系列1 - 也谈谈AlphaGo
- 【MicroPython ESP32】ssd1306驱动0.96“I2C屏幕cube3D图形显示