Description

题库链接

给定一棵有 \(n\) 个节点的无根树和 \(m\) 个操作,操作有 \(2\) 类:

  1. 将节点 \(a\) 到节点 \(b\) 路径上所有点都染成颜色 \(c\) ;
  2. 询问节点 \(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]染色的更多相关文章

  1. [BZOJ 2243] [SDOI 2011] 染色 【树链剖分】

    题目链接:BZOJ - 2243 题目分析 树链剖分...写了200+行...Debug了整整一天+... 静态读代码读了 5 遍 ,没发现错误,自己做小数据也过了. 提交之后全 WA . ————— ...

  2. BZOJ 2243 SDOI 2011染色

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2243 算法讨论: 树链剖分把树放到线段树上.然后线段树的每个节点要维护的东西有左端点的颜色 ...

  3. 解题: SDOI 2011 染色

    题面 强行把序列问题通过树剖套在树上...算了算是回顾了一下树剖的思想=.= 每次树上跳的时候注意跳的同时维护当前拼出来的左右两条链的靠上的端点,然后拼起来的时候讨论一下拼接点,最后一下左右两边的端点 ...

  4. 【SDOI 2011】染色

    [题目链接] 点击打开链接 [算法] 树链剖分 [代码] 本题,笔者求最近公共祖先并没有用树链剖分“往上跳”的方式,而是用倍增法.笔者认为这样比较好写,代码可读性 比较高 此外,笔者的线段树并没有用懒 ...

  5. 【codevs 1565】【SDOI 2011】计算器 快速幂+拓展欧几里得+BSGS算法

    BSGS算法是meet in the middle思想的一种应用,参考Yveh的博客我学会了BSGS的模版和hash表模板,,, 现在才会hash是不是太弱了,,, #include<cmath ...

  6. [bzoj2286][Sdoi 2011]消耗战

    [bzoj2286]消耗战 标签: 虚树 DP 题目链接 题解 很容易找出\(O(mn)\)的做法. 只需要每次都dp一遍. 但是m和n是同阶的,所以这样肯定会T的. 注意到dp的时候有很多节点是不需 ...

  7. [SDOI 2011]黑白棋

    Description 题库链接 给出一个 \(1\times n\) 的棋盘,棋盘上有 \(k\) 个棋子,一半是黑色,一半是白色.最左边是白色棋子,最右边是黑色棋子,相邻的棋子颜色不同. 小 \( ...

  8. [SDOI 2011]消耗战

    Description 题库链接 给你一棵 \(n\) 个节点根节点为 \(1\) 的有根树,有边权. \(m\) 次询问,每次给出 \(k_i\) 个关键点.询问切断一些边,使这些点到根节点不连通, ...

  9. [SDOI 2011]计算器

    Description 你被要求设计一个计算器完成以下三项任务: 1.给定y,z,p,计算Y^Z Mod P 的值: 2.给定y,z,p,计算满足xy≡ Z ( mod P )的最小非负整数: 3.给 ...

随机推荐

  1. 使用Flask-SQLAlchemy管理数据库

    SQLAlchemy 是一个很强大的关系型数据库框架,处于数据库抽象层 ,支持多种数据库后台. 提供了高层 ORM,也提供了使用数据库原生 SQL 的低层功能. 安装Flask-SQLAlchemy ...

  2. 201621123040《Java程序设计》第七周学习总结

    1.本周学习总结 1.1思维导图:Java图形界面总结 2.书面作业 2.1GUI中的事件处理 2.1.1写出事件处理模型中最重要的几个关键词. 关键词:事件 事件源 事件监听器 2.1.2任意编写事 ...

  3. 敏捷开发每日报告--day4

    1 团队介绍 团队组成: PM:齐爽爽(258) 小组成员:马帅(248),何健(267),蔡凯峰(285)  Git链接:https://github.com/WHUSE2017/C-team 2 ...

  4. django模型——数据库(二)

    模型--数据库(二) 实验简介 模型的一些基本操作,save方法用于把对象写入到数据库,objects是模型的管理器,可以使用它的delete.filter.all.order_by和update等函 ...

  5. 限定 edittext 的 输入内容

    <EditText                 android:id="@+id/idNumber"                 style="@style ...

  6. sql 用临时表时报错 "Chinese_PRC_90_CI_AI" 和 "Chinese_PRC_CI_AS" 之间的排序规则冲突

    在用临时表关联数据库中的表做关联查询时,如果报这种情况的话,就要把临时表和关联的表的排序规则统一掉. LEFT JOIN #tsub ON #tsub.joinjarno collate Chines ...

  7. JavaScript AJAX实例

    原生JS实现AJAX: // method : 请求方式 POST/GET; // url: 如果为GET方式的话url里面要带参数 // obj: 准备好的容器,方便储存拿到的数据 function ...

  8. 敏捷项目需求拆解&发现用户故事

    需求文档和敏捷中的Epic,User Story, Task之间是什么关系以及如何将需求文档转换成敏捷方式的描述,指导开发人员. 一直是很多公司团队比较困扰的问题,那么最近笔者为了解决这些问题,上了一 ...

  9. express实践(一)

    涉及以下这些内容: 主体. cookie.session 数据 模板引擎 服务器基本结构: const express=require('express'); const static=require ...

  10. ubuntu16.04下安装chrome

    1.在终端中,输入以下命令: sudo wget http://www.linuxidc.com/files/repo/google-chrome.list -P /etc/apt/sources.l ...