2243: [SDOI2011]染色

Description

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

1、将节点a到节点b路径上所有点都染成颜色c;

2、询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段),如“112221”由3段组成:“11”、“222”和“1”。

请你写一个程序依次完成这m个操作。

Input

第一行包含2个整数n和m,分别表示节点数和操作数;

第二行包含n个正整数表示n个节点的初始颜色

下面 行每行包含两个整数x和y,表示xy之间有一条无向边。

下面 行每行描述一个操作:

“C a b c”表示这是一个染色操作,把节点a到节点b路径上所有点(包括a和b)都染成颜色c;

“Q a b”表示这是一个询问操作,询问节点a到节点b(包括a和b)路径上的颜色段数量。

Output

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

Sample Input

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 3 5

C 5 1 2

Q 3 5

Sample Output

3

1

2

HINT

数N<=10^5,操作数M<=10^5,所有的颜色C为整数且在[0, 10^9]之间。

题解:

  树链剖分后,在相应的标号上进行线段树操作

#include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define ls i<<1
#define rs ls | 1
#define mid ((ll+rr)>>1)
#define pii pair<int,int>
#define MP make_pair
typedef long long LL;
const long long INF = 1e18+1LL;
const double Pi = acos(-1.0);
const int N = 5e5+, M = 1e3+, mod = 1e9+, inf = 2e9; int dep[N],head[N],t=,sz[N],fa[N],indexS,top[N],pos[N];
struct ss{int to,next;}e[N*];
int n;
void add(int u,int v)
{e[t].to = v;e[t].next = head[u];head[u] = t++;} void dfs(int u) {
sz[u] = ;
dep[u] = dep[fa[u]] + ;
for(int i = head[u]; i; i = e[i].next) {
int to = e[i].to;
if(to == fa[u]) continue;
fa[to] = u;
dfs(to);
sz[u] += sz[to];
}
}
void dfs(int u,int chain) {
int k = ;
pos[u] = ++indexS;
top[u] = chain;
for(int i = head[u]; i; i = e[i].next) {
int to = e[i].to;
if(dep[to] > dep[u] && sz[to] > sz[k])
k = to;
}
if(k == ) return ;
dfs(k,chain);
for(int i = head[u]; i; i = e[i].next) {
int to = e[i].to;
if(dep[to] > dep[u] && k != to)
dfs(to,to);
}
} LL lx[N],rx[N],mx[N],sum[N],lazy[N],fposs[N];
void push_up(int i) {
sum[i] = sum[ls] + sum[rs];
if(rx[ls] == lx[rs]) sum[i]-=;
lx[i] = lx[ls];rx[i] = rx[rs];
}
void build(int i,int ll,int rr) {
if(ll == rr) {
lx[i] = fposs[ll];
rx[i] = fposs[ll];
sum[i] = ;
return ;
}
build(ls,ll,mid),build(rs,mid+,rr);
push_up(i);
}
void push_down(int i,int ll,int rr) {
if(lazy[i] && ll != rr) {
lazy[ls] = lazy[i];
lazy[rs] = lazy[i];
lx[ls] = lazy[i];
rx[ls] = lazy[i];
lx[rs] = lazy[i];
rx[rs] = lazy[i];
sum[ls] = ;
sum[rs] = ;
lazy[i] = ;
}
}
void update(int i,int ll,int rr,int x,int y,int c) {
push_down(i,ll,rr);
if(ll == x && rr == y) {
lazy[i] = c;
lx[i] = c;
rx[i] = c;
sum[i] = ;
return ;
}
if(y <= mid) update(ls,ll,mid,x,y,c);
else if(x > mid) update(rs,mid+,rr,x,y,c);
else {
update(ls,ll,mid,x,mid,c);
update(rs,mid+,rr,mid+,y,c);
}
push_up(i);
}
void change(int x,int y,int c) {
while(top[x] != top[y]) {
if(dep[top[x]] < dep[top[y]]) swap(x,y);
update(,,n,pos[top[x]],pos[x],c);
x = fa[top[x]];
}
if(dep[x] > dep[y]) swap(x,y);
update(,,n,pos[x],pos[y],c);
}
int query(int i,int ll,int rr,int x,int y) {
push_down(i,ll,rr);
if(ll == x && rr == y) return sum[i];
if(y <= mid) return query(ls,ll,mid,x,y);
else if(x > mid) return query(rs,mid+,rr,x,y);
else return (query(ls,ll,mid,x,mid) + query(rs,mid+,rr,mid+,y) - (lx[rs] == rx[ls]));
push_up(i);
}
int color(int i,int ll,int rr,int x) {
push_down(i,ll,rr);
if(ll == rr) return lx[i];
if(x <= mid) return color(ls,ll,mid,x);
else return color(rs,mid+,rr,x);
push_up(i);
}
int query(int x,int y) {
int res = ,lastx = -,lasty = -;
while(top[x] != top[y]) {
if(dep[top[x]] > dep[top[y]]) {
res += query(,,n,pos[top[x]],pos[x]);
if(color(,,n,pos[x]) == lastx) res--;
lastx = color(,,n,pos[top[x]]);
x = fa[top[x]];
}
else {
res += query(,,n,pos[top[y]],pos[y]);
if(color(,,n,pos[y]) == lasty) res--;
lasty = color(,,n,pos[top[y]]);
y = fa[top[y]];
}
}
if(dep[x] < dep[y])res += query(,,n,pos[x],pos[y]);
else res += query(,,n,pos[y],pos[x]);
if(color(,,n,pos[x]) == lastx) res--;
if(color(,,n,pos[y]) == lasty) res--;
return res;
}
int Q,a[N],x,y;
char ch[N];
int main() {
scanf("%d%d",&n,&Q);
for(int i = ; i <= n; ++i) scanf("%d",&a[i]);
for(int i = ; i < n; ++i) {
scanf("%d%d",&x,&y);
add(x,y);
add(y,x);
}
dfs();
dfs(,);
for(int i = ; i <= n; ++i) fposs[pos[i]] = a[i];
build(,,n);
while(Q--) {
int a,b,c;
scanf("%s",ch);
if(ch[] == 'Q') {
scanf("%d%d",&a,&b);
printf("%d\n",query(a,b));
}else {
scanf("%d%d%d",&a,&b,&c);
change(a,b,c);
}
}
return ;
} /*
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 3 5
C 5 1 2
Q 3 5
*/

BZOJ 2243: [SDOI2011]染色 树链剖分+线段树区间合并的更多相关文章

  1. 2243: [SDOI2011]染色 树链剖分+线段树染色

    给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段), 如“112221”由3段组 ...

  2. bzoj2243[SDOI2011]染色 树链剖分+线段树

    2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 9012  Solved: 3375[Submit][Status ...

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

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

  4. B20J_2243_[SDOI2011]染色_树链剖分+线段树

    B20J_2243_[SDOI2011]染色_树链剖分+线段树 一下午净调这题了,争取晚上多做几道. 题意: 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成 ...

  5. BZOJ2243 [SDOI2011]染色(树链剖分+线段树合并)

    题目链接 BZOJ2243 树链剖分 $+$ 线段树 线段树每个节点维护$lc$, $rc$, $s$ $lc$代表该区间的最左端的颜色,$rc$代表该区间的最右端的颜色 $s$代表该区间的所有连续颜 ...

  6. BZOJ.4034 [HAOI2015]树上操作 ( 点权树链剖分 线段树 )

    BZOJ.4034 [HAOI2015]树上操作 ( 点权树链剖分 线段树 ) 题意分析 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 ...

  7. BZOJ.1036 [ZJOI2008]树的统计Count ( 点权树链剖分 线段树维护和与最值)

    BZOJ.1036 [ZJOI2008]树的统计Count (树链剖分 线段树维护和与最值) 题意分析 (题目图片来自于 这里) 第一道树链剖分的题目,谈一下自己的理解. 树链剖分能解决的问题是,题目 ...

  8. BZOJ 3672[NOI2014]购票(树链剖分+线段树维护凸包+斜率优化) + BZOJ 2402 陶陶的难题II (树链剖分+线段树维护凸包+分数规划+斜率优化)

    前言 刚开始看着两道题感觉头皮发麻,后来看看题解,发现挺好理解,只是代码有点长. BZOJ 3672[NOI2014]购票 中文题面,题意略: BZOJ 3672[NOI2014]购票 设f(i)f( ...

  9. bzoj 4196 [Noi2015]软件包管理器 (树链剖分+线段树)

    4196: [Noi2015]软件包管理器 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 2852  Solved: 1668[Submit][Sta ...

  10. bzoj 2157: 旅游【树链剖分+线段树】

    裸的树链剖分+线段树 但是要注意一个地方--我WA了好几次才发现取完相反数之后max值和min值是要交换的-- #include<iostream> #include<cstdio& ...

随机推荐

  1. Java方法传递参数传值还是传址的问题

    这几天重构项目代码遇到一个疑问:可不可以在方法A中定义一个boolean变量b为false,然后A调用方法C把b传递到C方法中经过一些列业务判断后修改为true,C执行结束后A方法中b的值还是原来的f ...

  2. Python数据可视化库-Matplotlib(二)

    我们接着上次的继续讲解,先讲一个概念,叫子图的概念. 我们先看一下这段代码 import matplotlib.pyplot as plt fig = plt.figure() ax1 = fig.a ...

  3. SCI journals on Energy

    SCI journals on Energy Table of Contents 1. SCI- Clarivate - Thomson Reuters 1 SCI- Clarivate - Thom ...

  4. solr 时区问题

    本人使用solr版本5.0.0,使用jetty启动 solr默认UTC时区,与我们相差八小时,按照网络上资料修改 C:\Users\hp\Desktop\solr-5.0.0\bin 下的solr.i ...

  5. POJ 3310 Caterpillar(图的度的判定)

    题意: 给定一幅图, 问符不符合一下两个条件: (1) 图中没有环 (2)图中存在一条链, 点要么在链上, 要么是链上点的邻居. 分析: 建图,记录度数, 去掉所有度为1的点, 然后看看剩下是否是有2 ...

  6. HDU 6216 A Cubic number and A Cubic Number(数学/二分查找)

    题意: 给定一个素数p(p <= 1e12),问是否存在一对立方差等于p. 分析: 根据平方差公式: 因为p是一个素数, 所以只能拆分成 1*p, 所以 a-b = 1. 然后代入a = b + ...

  7. 算法导论 第十三章 红黑树(python)-1插入

    红黑树是上一章二叉搜索树的改进,实现一种平衡 ,保证不会出现二叉树变链表的情况,基本动态集合操作的时间复杂度为O(lgn) 实际用途:c++stl中的set,map是用他实现的 红黑树的性质: 1.每 ...

  8. ubunt设置终端快捷键设置 及 常用快捷键

    Ctrl+A:将光标移动到命令行的开始处. Ctrl+E:将光标移动到命行令的结尾处. Ctrl+U:删除行首到光标出的字符. Ctrl+Z:把当前进程送到后台处理.  &    bg 部分快 ...

  9. xtu read problem training B - Tour

    B - Tour Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Descriptio ...

  10. Codeforces Round #269 (Div. 2)-D. MUH and Cube Walls,KMP裸模板拿走!

    D. MUH and Cube Walls 说实话,这题看懂题意后秒出思路,和顺波说了一下是KMP,后来过了一会确定了思路他开始写我中途接了个电话,回来kaungbin模板一板子上去直接A了. 题意: ...