BZOJ 2243: [SDOI2011]染色 树链剖分+线段树区间合并
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,表示x和y之间有一条无向边。
下面 行每行描述一个操作:
“C a b c”表示这是一个染色操作,把节点a到节点b路径上所有点(包括a和b)都染成颜色c;
“Q a b”表示这是一个询问操作,询问节点a到节点b(包括a和b)路径上的颜色段数量。
Output
对于每个询问操作,输出一行答案。
Sample Input
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
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]染色 树链剖分+线段树区间合并的更多相关文章
- 2243: [SDOI2011]染色 树链剖分+线段树染色
给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段), 如“112221”由3段组 ...
- bzoj2243[SDOI2011]染色 树链剖分+线段树
2243: [SDOI2011]染色 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 9012 Solved: 3375[Submit][Status ...
- 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树
[BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...
- B20J_2243_[SDOI2011]染色_树链剖分+线段树
B20J_2243_[SDOI2011]染色_树链剖分+线段树 一下午净调这题了,争取晚上多做几道. 题意: 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成 ...
- BZOJ2243 [SDOI2011]染色(树链剖分+线段树合并)
题目链接 BZOJ2243 树链剖分 $+$ 线段树 线段树每个节点维护$lc$, $rc$, $s$ $lc$代表该区间的最左端的颜色,$rc$代表该区间的最右端的颜色 $s$代表该区间的所有连续颜 ...
- BZOJ.4034 [HAOI2015]树上操作 ( 点权树链剖分 线段树 )
BZOJ.4034 [HAOI2015]树上操作 ( 点权树链剖分 线段树 ) 题意分析 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 ...
- BZOJ.1036 [ZJOI2008]树的统计Count ( 点权树链剖分 线段树维护和与最值)
BZOJ.1036 [ZJOI2008]树的统计Count (树链剖分 线段树维护和与最值) 题意分析 (题目图片来自于 这里) 第一道树链剖分的题目,谈一下自己的理解. 树链剖分能解决的问题是,题目 ...
- BZOJ 3672[NOI2014]购票(树链剖分+线段树维护凸包+斜率优化) + BZOJ 2402 陶陶的难题II (树链剖分+线段树维护凸包+分数规划+斜率优化)
前言 刚开始看着两道题感觉头皮发麻,后来看看题解,发现挺好理解,只是代码有点长. BZOJ 3672[NOI2014]购票 中文题面,题意略: BZOJ 3672[NOI2014]购票 设f(i)f( ...
- bzoj 4196 [Noi2015]软件包管理器 (树链剖分+线段树)
4196: [Noi2015]软件包管理器 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 2852 Solved: 1668[Submit][Sta ...
- bzoj 2157: 旅游【树链剖分+线段树】
裸的树链剖分+线段树 但是要注意一个地方--我WA了好几次才发现取完相反数之后max值和min值是要交换的-- #include<iostream> #include<cstdio& ...
随机推荐
- 如何用纯 CSS 创作一种按钮被瞄准的交互特效
效果预览 按下右侧的"点击预览"按钮在当前页面预览,点击链接全屏预览. 在线演示 https://codepen.io/zhang-ou/pen/ELWMLr 可交互视频教程 此视 ...
- 条款26:尽可能延后变量定义式的出现时间(Postpone variable definitions as long as possible)
NOTE : 1.尽可能延后变量定义式的出现时间.这样做可增加程序的清晰度并改善程序效率.
- python基础知识07-函数作用域和匿名函数
1.匿名函数 list(filter(lamda a:a>3,[1,2,3,4,5])) 一般和过滤器一起使用 2.函数的作用域 a = 123 def test(): a = 666 a = ...
- Django框架基础知识11-会话状态保持及表单
浏览器存储cookie的方式不太安全,那有没有更好些的来存储登入状态的方式呢??? 状态保持----cookie和session: 状态保持: 1.http协议是无状态的:每次请求都是一次新的请求,不 ...
- CentOS 7 设置开机自启动
创建脚本: #!/bin/bash echo "hello!" # 启动虚拟环境 cd /data/env/crmenv/bin/ source activ ...
- 【02】一个实现h5的拖放的整个过程-魔芋
[02]拖放的整个过程-魔芋 01,创建2个元素,一个为拖放元素dragEle,一个是存放的元素targetEle.添加一些样式. <div class="dragEle&qu ...
- BootStrap学习01框架搭建
中文文档:https://v3.bootcss.com/css/ 开发工具 WebStorm 一.新建项目08bootstrap 引入bootstrap-3.3.7,引入jQuery,引入holder ...
- 一个jboss启动shell脚本
脚本1: #!/bin/sh # paulo@evencom.com.br #JBOSS_HOME JBOSS_HOME="/opt/app/jboss-eap-6.3" JAVA ...
- CodeForces 632A
A - Grandma Laura and Apples Time Limit:1000MS Memory Limit:262144KB 64bit IO Format:%I64d & ...
- HDU 3527 SPY
http://poj.org/problem?id=3615 基础题 狂STL #include <bits/stdc++.h> using namespace std; set<s ...