[SDOI 2011]染色
Description
给定一棵有 \(n\) 个节点的无根树和 \(m\) 个操作,操作有 \(2\) 类:
- 将节点 \(a\) 到节点 \(b\) 路径上所有点都染成颜色 \(c\) ;
- 询问节点 \(a\) 到节点 \(b\) 路径上的颜色段数量(连续相同颜色被认为是同一段)
Solution
线段树苟题。因为没有下传 \(lazy\) 标记调了一上午。
Code
//It is made by Awson on 2018.3.4
#include <bits/stdc++.h>
#define LL long long
#define dob complex<double>
#define Abs(a) ((a) < 0 ? (-(a)) : (a))
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define Min(a, b) ((a) < (b) ? (a) : (b))
#define Swap(a, b) ((a) ^= (b), (b) ^= (a), (a) ^= (b))
#define writeln(x) (write(x), putchar('\n'))
#define lowbit(x) ((x)&(-(x)))
using namespace std;
const int N = 1e5;
void read(int &x) {
char ch; bool flag = 0;
for (ch = getchar(); !isdigit(ch) && ((flag |= (ch == '-')) || 1); ch = getchar());
for (x = 0; isdigit(ch); x = (x<<1)+(x<<3)+ch-48, ch = getchar());
x *= 1-2*flag;
}
void print(int x) {if (x > 9) print(x/10); putchar(x%10+48); }
void write(int x) {if (x < 0) putchar('-'); print(Abs(x)); }
int n, m, c[N+5], a[N+5], u, v, ca;
struct tt {int to, next; }edge[(N<<1)+5];
int path[N+5], Top;
int size[N+5], id[N+5], son[N+5], top[N+5], dep[N+5], fa[N+5], pos;
char ch[5];
struct node {
int l, r, cnt;
node() {}
node(int _l, int _r, int _cnt) {l = _l, r = _r, cnt = _cnt; }
node operator + (const node &b) const {node tmp; tmp.l = l, tmp.r = b.r, tmp.cnt = cnt+b.cnt-(r==b.l); return tmp; }
};
struct Segment_tree {
#define lr(o) (o<<1)
#define rr(o) (o<<1|1)
node sgm[(N<<2)+5]; int lazy[(N<<2)+5];
void pushdown(int o) {sgm[lr(o)] = sgm[rr(o)] = sgm[o]; lazy[lr(o)] = lazy[rr(o)] = 1; lazy[o] = 0; }
void build(int o, int l, int r) {
if (l == r) {sgm[o] = node(a[l], a[l], 1); return; }
int mid = (l+r)>>1;
build(lr(o), l, mid); build(rr(o), mid+1, r); sgm[o] = sgm[lr(o)]+sgm[rr(o)];
}
node query(int o, int l, int r, int a, int b) {
if (a <= l && r <= b) return sgm[o];
if (lazy[o]) pushdown(o); int mid = (l+r)>>1;
if (b <= mid) return query(lr(o), l, mid, a, b);
if (a > mid) return query(rr(o), mid+1, r, a, b);
return query(lr(o), l, mid, a, b)+query(rr(o), mid+1, r, a, b);
}
void update(int o, int l, int r, int a, int b, int col) {
if (a <= l && r <= b) {sgm[o] = node(col, col, 1), lazy[o] = 1; return; }
if (lazy[o]) pushdown(o); int mid = (l+r)>>1;
if (a <= mid) update(lr(o), l, mid, a, b, col);
if (b > mid) update(rr(o), mid+1, r, a, b, col);
sgm[o] = sgm[lr(o)]+sgm[rr(o)];
}
}T;
void add(int u, int v) {edge[++Top].to = v, edge[Top].next = path[u], path[u] = Top; }
void dfs1(int o, int depth, int father) {
dep[o] = depth, size[o] = 1, fa[o] = father;
for (int i = path[o]; i; i = edge[i].next)
if (dep[edge[i].to] == 0) {
dfs1(edge[i].to, depth+1, o); size[o] += size[edge[i].to];
if (size[edge[i].to] > size[son[o]]) son[o] = edge[i].to;
}
}
void dfs2(int o, int tp) {
id[o] = ++pos, a[pos] = c[o], top[o] = tp;
if (son[o]) dfs2(son[o], tp);
for (int i = path[o]; i; i = edge[i].next)
if (edge[i].to != fa[o] && edge[i].to != son[o]) dfs2(edge[i].to, edge[i].to);
}
void update(int u, int v, int c) {
while (top[u] != top[v]) {
if (dep[top[u]] < dep[top[v]]) Swap(u, v);
T.update(1, 1, n, id[top[u]], id[u], c);
u = fa[top[u]];
}
if (dep[u] < dep[v]) Swap(u, v);
T.update(1, 1, n, id[v], id[u], c);
}
int query(int u, int v) {
node n1, n2; int f1 = 1, f2 = 1;
while (top[u] != top[v]) {
if (dep[top[u]] > dep[top[v]]) {
if (f1) n1 = T.query(1, 1, n, id[top[u]], id[u]);
else n1 = T.query(1, 1, n, id[top[u]], id[u])+n1;
u = fa[top[u]]; f1 = 0;
}else {
if (f2) n2 = T.query(1, 1, n, id[top[v]], id[v]);
else n2 = T.query(1, 1, n, id[top[v]], id[v])+n2;
v = fa[top[v]]; f2 = 0;
}
}
if (dep[u] > dep[v]) {
if (f1) n1 = T.query(1, 1, n, id[v], id[u]);
else n1 = T.query(1, 1, n, id[v], id[u])+n1; f1 = 0;
}else {
if (f2) n2 = T.query(1, 1, n, id[u], id[v]);
else n2 = T.query(1, 1, n, id[u], id[v])+n2; f2 = 0;
}
if (f1) return n2.cnt;
if (f2) return n1.cnt;
Swap(n1.l, n1.r); n1 = n1+n2; return n1.cnt;
}
void work() {
read(n), read(m); for (int i = 1; i <= n; i++) read(c[i]);
for (int i = 1; i < n; i++) read(u), read(v), add(u, v), add(v, u);
dfs1(1, 1, 0), dfs2(1, 1); T.build(1, 1, n);
while (m--) {
scanf("%s", ch);
if (ch[0] == 'Q') read(u), read(v), writeln(query(u, v));
else read(u), read(v), read(ca), update(u, v, ca);
}
}
int main() {
work(); return 0;
}
[SDOI 2011]染色的更多相关文章
- [BZOJ 2243] [SDOI 2011] 染色 【树链剖分】
题目链接:BZOJ - 2243 题目分析 树链剖分...写了200+行...Debug了整整一天+... 静态读代码读了 5 遍 ,没发现错误,自己做小数据也过了. 提交之后全 WA . ————— ...
- BZOJ 2243 SDOI 2011染色
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2243 算法讨论: 树链剖分把树放到线段树上.然后线段树的每个节点要维护的东西有左端点的颜色 ...
- 解题: SDOI 2011 染色
题面 强行把序列问题通过树剖套在树上...算了算是回顾了一下树剖的思想=.= 每次树上跳的时候注意跳的同时维护当前拼出来的左右两条链的靠上的端点,然后拼起来的时候讨论一下拼接点,最后一下左右两边的端点 ...
- 【SDOI 2011】染色
[题目链接] 点击打开链接 [算法] 树链剖分 [代码] 本题,笔者求最近公共祖先并没有用树链剖分“往上跳”的方式,而是用倍增法.笔者认为这样比较好写,代码可读性 比较高 此外,笔者的线段树并没有用懒 ...
- 【codevs 1565】【SDOI 2011】计算器 快速幂+拓展欧几里得+BSGS算法
BSGS算法是meet in the middle思想的一种应用,参考Yveh的博客我学会了BSGS的模版和hash表模板,,, 现在才会hash是不是太弱了,,, #include<cmath ...
- [bzoj2286][Sdoi 2011]消耗战
[bzoj2286]消耗战 标签: 虚树 DP 题目链接 题解 很容易找出\(O(mn)\)的做法. 只需要每次都dp一遍. 但是m和n是同阶的,所以这样肯定会T的. 注意到dp的时候有很多节点是不需 ...
- [SDOI 2011]黑白棋
Description 题库链接 给出一个 \(1\times n\) 的棋盘,棋盘上有 \(k\) 个棋子,一半是黑色,一半是白色.最左边是白色棋子,最右边是黑色棋子,相邻的棋子颜色不同. 小 \( ...
- [SDOI 2011]消耗战
Description 题库链接 给你一棵 \(n\) 个节点根节点为 \(1\) 的有根树,有边权. \(m\) 次询问,每次给出 \(k_i\) 个关键点.询问切断一些边,使这些点到根节点不连通, ...
- [SDOI 2011]计算器
Description 你被要求设计一个计算器完成以下三项任务: 1.给定y,z,p,计算Y^Z Mod P 的值: 2.给定y,z,p,计算满足xy≡ Z ( mod P )的最小非负整数: 3.给 ...
随机推荐
- 2018上C语言程序设计(高级)- 第0次作业成绩
作业链接: https://edu.cnblogs.com/campus/hljkj/CS201702/homework/1617 评分规则 本次作业作为本学期的第一次作业,大家态度较诚恳,篇幅都比较 ...
- C语言程序设计(基础)- 第3周作业
一.PTA编程题目 完成PTA第三周作业中4个题目: 1.7-9 A乘以B 要求:输入的两个整数:A是你学号前两位数字,B是你学号后两位数字 2.7-10 求整数均值 要求:输入的整数是:你的身高.体 ...
- Beta 集合
Beta冲刺序列: Beta凡事预则立 :Beta No.0 Beta冲刺Day1:Beta No.1 Beta冲刺Day2:Beta No.2 Beta冲刺Day3:Beta No.3 Beta冲刺 ...
- react基础篇入门组件
讲述一下React: 1.声明式设计-React采用声明范式,可以轻松描述应用 2.高效-React通过DOM模型,最大限度的减少dom的交互 3.灵活-React可以与已知的库或框架很好的配合 4. ...
- 遍历JSON
第一种: each,不做详细说明,太常用了 第二种:我用来遍历单个组,实现前端界面绑定 for(var item in person){ alert("person中"+item+ ...
- 使用 Vue 和 epub.js 制作电子书阅读器
ePub 简介 ePub 是一种电子书的标准格式,平时我看的电子书大部分是这种格式.在手机上我一般用"多看"阅读 ePub 电子书,在 Windows 上找不到用起来比较顺心的软件 ...
- 作业五:RE 模块模拟计算器
# !/usr/bin/env python3 # _*_coding:utf-8_*_ ''' 实现模拟计算器的功能: 公式: - * ( (- +(-/) * (-*/ + /*/* + * / ...
- 安装 go 语言环境
操作系统: CentOS 6.9_x64 go语言版本: 1.8.3 安装go 这里直接安装二进制,其它方式请自行搜索. 1.下载并安装go 命令如下: ? 1 2 3 wget https://st ...
- GIT入门笔记(8)-- 查看历史提交记录/根据版本号回到过去或未来
在Git中,用HEAD表示当前版本,也就是最新的提交版本, 上一个版本就是HEAD^, 上上一个版本就是HEAD^^, 往上100个版本写100个^比较容易数不过来,所以写成HEAD~100. Git ...
- MYSQL 面试查询系列问题
表结构: `student`('id'.'name'.'code'.'age'.'sex')学生表 `teacher`('id'.'name')教师表 `course`('id'.'name'.'te ...