可爱的树链剖分(染色)

这道题 就是 一道 普通的! 树链剖分+线段树覆盖

注意一下两个线段树合并的时候 如果 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 的时候 最后的判断语句一定不能改方向(为什么呢我不知道) 我好难受啊

可爱的树链剖分(染色)相关推荐

  1. [树链剖分][SDOI 2011]染色,Housewife Wind

    文章目录 T1:Housewife Wind 题目 题解 code T2:染色 题目 题解 code 今天选择写这篇博客主要是为了告诉大家一个道理,数组比vectorvectorvector快太多了, ...

  2. BZOJ 2243 染色(树链剖分好题)

    2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 512 MB Submit: 7971  Solved: 2990 [Submit][Stat ...

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

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

  4. 【YBT2022寒假Day8 A】染色计划(Tarjan)(线段树优化建边)(树链剖分)

    染色计划 题目链接:YBT2022寒假Day8 A 题目大意 给你一棵树,然后有 k 中颜色,每个点有一个颜色,然后问你要修改多少次,才能使得一个存在的颜色的所有点构成一个连通块. 一个修改操作指选择 ...

  5. 树链剖分——线段树区间合并bzoj染色

    线段树区间合并就挺麻烦了,再套个树链就更加鬼畜,不过除了代码量大就没什么其他的了.. 一些细节:线段树每个结点用结构体保存,pushup等合并函数改成返回一个结构体,这样好写一些 struct Seg ...

  6. 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 ...

  7. 【树链剖分】染色(luogu 2486/金牌导航 树链剖分-3)

    正题 luogu 2486 金牌导航 树链剖分-3 题目大意 给你一棵树,让你进行以下操作: 1.把一条路径染上一个颜色 2.查询一条路径上有多少个颜色段 解题思路 用树链剖分把问题转化为链上问题 然 ...

  8. 【BZOJ2243】【codevs1566】染色,树链剖分练习

    传送门1 传送门2 写在前面:比一些裸题好多了-- 思路:典型的树链剖分,不过我们要存储的是每段区间内颜色段数量,对于这个问题,显然我们要存下整个区间的详细状态是不可能的,但可以把这个区间的左右端点记 ...

  9. 洛谷P2486 [SDOI2011]染色(树链剖分+线段树判断边界)

    [题目链接] [思路]: 涉及到树上区间修改操作,所以使用树链剖分,涉及到区间查询,所以使用线段树. update操作时,就正常操作,难点在于query操作的计数. 因为树链剖分的dfs序只能保证一条 ...

最新文章

  1. Intel Realsense D435 将深度图的灰度图映射为彩色图,打印输出灰度图或彩色图
  2. boost::fibers模块实现适配方法调用的测试程序
  3. DisplayPowerState
  4. HttpURLConnection和HttpClient的简单用法
  5. Tips--TensorFlow报错:tensorflow:Early stopping conditioned on metric `val_loss` which is not available
  6. 北师大版图形的旋转二教案_新北师大版八年级下册数学 《图形的旋转(2)》教案...
  7. Atitit alldiaryindex v1 t717 目录 1. Fix 1 2. Diary detail 1 2.1. Diary 1987---2016.12 1 2.2. Diary20
  8. 国际冠码与国际电话区号
  9. 关于 移动硬盘数据丢失问题 的解决方法
  10. CAD修复块中心点(网页版)
  11. 小记!华为 8.0系统切换APP内语言(中英文)无效(其他版本手机均有效)。
  12. matlab multiply,MATLAB Matrix Multiply Code效率
  13. UVM:一个简易验证平台例子
  14. 微信 SHA1 签名_微信公众号自动回复功能开发
  15. R语言实战学习--回归
  16. iOS通过dSYM文件分析crash
  17. cmd的一些有趣命令
  18. sql查询今天,近七天,近一个月,近一年的数量统计
  19. 深入浅出WPF知识点汇总一
  20. 数据结构: 中序非递归遍历二叉树

热门文章

  1. java网课|static
  2. 解析USGS网站页面中的地震空间数据
  3. Dynamic Movement Primitives与UR5机械臂仿真
  4. 阿里P10赵海平跳槽字节跳动:深度解析跳槽从开始到结束完整流程!
  5. django实训报告
  6. 制作服装推广软文html,服装行业软文怎么写,公众号服装分销软文推广!
  7. java如何编写spi接口_软件模拟SPI接口程序代码(4种模式)
  8. 【JS】隐匿在计算机软硬件背后的语言
  9. 文笔很差系列1 - 也谈谈AlphaGo
  10. 【MicroPython ESP32】ssd1306驱动0.96“I2C屏幕cube3D图形显示