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. mysql 5.7 windows zip安装

    mysql 官网下载windows zip 安装包 并解压 (D:wampmysql-56-winx64) 添加path D:wampmysql-5722-winx64bin 创建data目录 D:\ ...

  2. LeetCode(14)Longest Common Prefix

    题目 Write a function to find the longest common prefix string amongst an array of strings. 分析 该题目是求一个 ...

  3. Android开发——遍历读写U盘、SD卡等外部存储

    1.首先需要得到挂载在手机上的有哪些盘符 String[] result = null; StorageManager storageManager = (StorageManager)getSyst ...

  4. pip安装requests库失败

    pip install 安装第三方插件是出现Could not fetch URL https://pypi.python.org/simple/pool/: There was a problem ...

  5. XV6上下文切换

    上下文切换分为两种情况 用户程序陷入到内核,再从内核返回 两个应用程序之间的上下文切换 用户程序陷入到内核 用户程序陷入到内核通过中断INT指令,在xv6中系统调用的号为64 操作系统在初始化的时候会 ...

  6. HaHa's Morning(状压DP)

    描述 HaHa is so happy today, he is going to participate the 7th Hunan University Programming Contest. ...

  7. 什么是TLS?

    最近在Istio实验中经常遇到HTTP,HTTPS,TLS等名词,感觉忘得差不多,需要复习一下计算机网络的知识了. 本文参考   http://www.techug.com/post/https-ss ...

  8. JS把数字金额转换成中文大写数字的函数

    //把数字金额转换成中文大写数字的函数 function num2rmb ($num){ $c1="零壹贰叁肆伍陆柒捌玖"; $c2="分角元拾佰仟万拾佰仟亿" ...

  9. vagrant的学习 之 优化

    vagrant的学习 之 优化 一.修改虚拟机名字: 默认的虚拟机的名字很长:study_default_1535505004652_97747. (1)打开Vagrantfile文件:(2)找到: ...

  10. python学习之-- RabbitMQ 消息队列

    记录:异步网络框架:twisted学习参考:www.cnblogs.com/alex3714/articles/5248247.html RabbitMQ 模块 <消息队列> 先说明:py ...