P2486 [SDOI2011]染色 维护区间块数 树链剖分
题意
对一个树上维护两种操作,一种是把x到y间的点都染成c色,另一种是求x到y间的点有多少个颜色块,比如112221由“11”,“222”,“1”三块组成。
思路
这题的关键是要如何维护这个颜色块,我们可以利用线段树,记录每个区间的块数,区间左端点,区间右端点的颜色。合并中如果两个区间相邻点颜色相同,个数要减去1.
查询也是一样的,链与链间的相邻点也要考虑清楚。
- #include <algorithm>
- #include <iterator>
- #include <iostream>
- #include <cstring>
- #include <cstdlib>
- #include <iomanip>
- #include <bitset>
- #include <cctype>
- #include <cstdio>
- #include <string>
- #include <vector>
- #include <stack>
- #include <cmath>
- #include <queue>
- #include <list>
- #include <map>
- #include <set>
- #include <cassert>
- /*
- ⊂_ヽ
- \\ Λ_Λ 来了老弟
- \('ㅅ')
- > ⌒ヽ
- / へ\
- / / \\
- レ ノ ヽ_つ
- / /
- / /|
- ( (ヽ
- | |、\
- | 丿 \ ⌒)
- | | ) /
- 'ノ ) Lノ
- */
- using namespace std;
- #define lson (l , mid , rt << 1)
- #define rson (mid + 1 , r , rt << 1 | 1)
- #define debug(x) cerr << #x << " = " << x << "\n";
- #define pb push_back
- #define pq priority_queue
- typedef long long ll;
- typedef unsigned long long ull;
- //typedef __int128 bll;
- typedef pair<ll ,ll > pll;
- typedef pair<int ,int > pii;
- typedef pair<int,pii> p3;
- //priority_queue<int> q;//这是一个大根堆q
- //priority_queue<int,vector<int>,greater<int> >q;//这是一个小根堆q
- #define fi first
- #define se second
- //#define endl '\n'
- #define boost ios::sync_with_stdio(false);cin.tie(0)
- #define rep(a, b, c) for(int a = (b); a <= (c); ++ a)
- #define max3(a,b,c) max(max(a,b), c);
- #define min3(a,b,c) min(min(a,b), c);
- const ll oo = 1ll<<;
- const ll mos = 0x7FFFFFFF; //
- const ll nmos = 0x80000000; //-2147483648
- const int inf = 0x3f3f3f3f;
- const ll inff = 0x3f3f3f3f3f3f3f3f; //
- const ll mod = ;
- const double esp = 1e-;
- const double PI=acos(-1.0);
- const double PHI=0.61803399; //黄金分割点
- const double tPHI=0.38196601;
- template<typename T>
- inline T read(T&x){
- x=;int f=;char ch=getchar();
- while (ch<''||ch>'') f|=(ch=='-'),ch=getchar();
- while (ch>=''&&ch<='') x=x*+ch-'',ch=getchar();
- return x=f?-x:x;
- }
- inline void cmax(int &x,int y){if(x<y)x=y;}
- inline void cmax(ll &x,ll y){if(x<y)x=y;}
- inline void cmin(int &x,int y){if(x>y)x=y;}
- inline void cmin(ll &x,ll y){if(x>y)x=y;}
- /*-----------------------showtime----------------------*/
- const int maxn = 1e5+;
- int a[maxn],b[maxn];
- int dp[maxn],sz[maxn],fa[maxn],son[maxn];
- vector<int>mp[maxn];
- void dfs1(int u,int f,int deep){
- dp[u] = deep;
- fa[u] = f;
- sz[u] = ;
- int mx = ;
- for(int i=; i<mp[u].size(); i++){
- int v = mp[u][i];
- if(v == f) continue;
- dfs1(v, u, deep+);
- sz[u] += sz[v];
- if(sz[v] > mx) {mx = sz[v], son[u] = v;}
- }
- }
- int top[maxn],id[maxn],cnt = ;
- void dfs2(int u,int f,int topf){
- top[u] = topf;
- id[u] = ++cnt;
- b[cnt] = a[u];
- if(son[u])dfs2(son[u], u, topf);
- for(int i=; i<mp[u].size(); i++){
- int v = mp[u][i];
- if(v == f || v == son[u]) continue;
- dfs2(v, u, v);
- }
- }
- int tag[maxn<<],lazy[maxn<<],ly[maxn<<],rz[maxn<<];
- void pushup(int rt){
- tag[rt] = tag[rt<<] + tag[rt<<|];
- rz[rt] = rz[rt<<];
- ly[rt] = ly[rt<<|];
- if(ly[rt<<] == rz[rt<<|])tag[rt] --;
- }
- void build(int l,int r,int rt){
- if(l == r){
- tag[rt] = ;
- ly[rt] = rz[rt] = b[l];
- return ;
- }
- int mid = (l + r) >> ;
- build(l, mid, rt<<);
- build(mid+,r,rt<<|);
- pushup(rt);
- // cout<<l<<" "<<r<<" "<<rz[rt] << " " << ly[rt]<<endl;
- }
- void pushdown(int l,int r,int rt){
- tag[rt<<] = tag[rt<<|] = ;
- ly[rt<<] = rz[rt<<] = lazy[rt];
- ly[rt<<|] = rz[rt<<|] = lazy[rt];
- lazy[rt<<] = lazy[rt<<|] = lazy[rt];
- lazy[rt] = ;
- }
- void update(int L, int R, int c, int l, int r,int rt){
- if(l >= L && r <= R){
- tag[rt] = ;
- ly[rt] = rz[rt] = c;
- lazy[rt] = c;
- return;
- }
- int mid = (l + r) >> ;
- if(lazy[rt]) pushdown(l, r, rt);
- if(mid >= L) update(L, R, c, l, mid, rt<<);
- if(mid < R) update(L,R,c,mid+,r,rt<<|);
- pushup(rt);
- }
- int n,m;
- void solve(int x,int y,int c){
- while(top[x] != top[y]){
- if(dp[top[x]] < dp[top[y]]) swap(x, y);
- update(id[top[x]], id[x], c, , n, );
- x = fa[top[x]];
- }
- if(dp[x] > dp[y]) swap(x, y);
- update(id[x], id[y], c, , n, );
- }
- int query(int L,int R, int l,int r,int rt,int &tmpl,int &tmpr){
- if(l >= L && r<= R){
- if(l == L) tmpl = rz[rt];
- if(r == R) tmpr = ly[rt];
- return tag[rt];
- }
- int mid = (l + r) >> ;
- if(lazy[rt])pushdown(l, r, rt);
- int res = ;
- int ql = -, qr = -;
- if(mid >= L) {
- res += query(L, R, l, mid, rt<<,tmpl,tmpr);
- ql = ly[rt<<];
- }
- if(mid < R){
- res += query(L, R, mid +, r, rt<<|,tmpl,tmpr);
- qr = rz[rt<<|];
- }
- if(ql == qr && ql != -) res --;
- pushup(rt);
- return res;
- }
- int cal(int x,int y){
- int res = ,lax = -,lay=-;
- while(top[x] != top[y]){
- int tmpl = -,tmpr=-;
- if(dp[top[x]] > dp[top[y]]) {
- res += query(id[top[x]], id[x], , n, , tmpl, tmpr);//tmp,flag 1,r
- if(lax == tmpr) res--;
- lax = tmpl;
- x = fa[top[x]];
- }
- else {
- res += query(id[top[y]], id[y], , n, ,tmpl,tmpr);
- if(lay == tmpr) res--;
- lay = tmpl;
- y = fa[top[y]];
- }
- // cout<<tmpl<<" !! "<<tmpr<<endl;
- }
- if(dp[x] > dp[y]){
- int tmpl = -,tmpr=-;
- res += query(id[y], id[x], , n, ,tmpl,tmpr);
- if(tmpr == lax) res--;
- if(tmpl == lay) res--;
- }
- else {
- int tmpl = -,tmpr=-;
- res += query(id[x], id[y], , n, ,tmpl,tmpr);
- if(tmpl == lax) res--;
- if(tmpr == lay) res--;
- }
- return res;
- }
- int main(){
- scanf("%d%d", &n, &m);
- rep(i, , n) scanf("%d", &a[i]);
- rep(i, , n-) {
- int u,v;
- scanf("%d%d", &u, &v);
- mp[u].pb(v);
- mp[v].pb(u);
- }
- dfs1(, , );
- dfs2(, , );
- build(, n, );
- while(m--){
- char str[];
- scanf("%s", str);
- if(str[] == 'C') {
- int x,y,z;
- scanf("%d%d%d", &x, &y, &z);
- solve(x, y, z);
- }
- else {
- int x,y;
- scanf("%d%d", &x, &y);
- printf("%d\n", cal (x,y));
- }
- }
- return ;
- }
P2486 [SDOI2011]染色 维护区间块数 树链剖分的更多相关文章
- bzoj 2243: [SDOI2011]染色 线段树区间合并+树链剖分
2243: [SDOI2011]染色 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 7925 Solved: 2975[Submit][Status ...
- P2486 [SDOI2011]染色 区间合并+树链剖分(加深对线段树的理解)
#include<bits/stdc++.h> using namespace std; ; struct node{ int l,r,cnt,lazy; node(,,,):l(l1), ...
- P2486 [SDOI2011]染色 区间合并+树链剖分(加深对线段树的理解)
#include<bits/stdc++.h> using namespace std; ; struct node{ int l,r,cnt,lazy; node(,,,):l(l1), ...
- 2020牛客NOIP赛前集训营-提高组(第三场) C - 牛半仙的妹子Tree (树链剖分)
昨天教练问我:你用树剖做这道题,怎么全部清空状态呢? 我:???不是懒标记就完了??? 教练:树剖不是要建很多棵线段树吗,不止log个,你要一个一个清? 我:为什么要建很多棵线段树? ...
- luogu题解 P3950部落冲突--树链剖分
题目链接 https://www.luogu.org/problemnew/show/P3950 分析 大佬都用LCT,我太弱只会树链剖分 一个很裸的维护边权树链剖分题.按照套路,对于一条边\(< ...
- Luogu P2486 [SDOI2011]染色(树链剖分+线段树合并)
Luogu P2486 [SDOI2011]染色 题面 题目描述 输入输出格式 输入格式: 输出格式: 对于每个询问操作,输出一行答案. 输入输出样例 输入样例: 6 5 2 2 1 2 1 1 1 ...
- 洛谷 P2486 [SDOI2011]染色 树链剖分
目录 题面 题目链接 题目描述 输入输出格式 输入格式 输出格式 输入输出样例 输入样例: 输出样例: 说明 思路 PushDown与Update Q AC代码 总结与拓展 题面 题目链接 P2486 ...
- bzoj 2243: [SDOI2011]染色 (树链剖分+线段树 区间合并)
2243: [SDOI2011]染色 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 9854 Solved: 3725[Submit][Status ...
- P2486 [SDOI2011]染色(树剖)区间覆盖+区间的连续段
https://www.luogu.org/problemnew/show/P2486 值的一看https://www.cnblogs.com/Tony-Double-Sky/p/9283262.ht ...
随机推荐
- UE4 代理 BindRaw和BindUObject
代理允许您在C++对象上以通用的但类型安全的方式调用成员函数.通过使用代理,可以将其动态地绑定到任何对象的成员函数上,然后在该对象上调用函数,即时调用者不知道该对象的类型也没关系. 任何时候都应该通过 ...
- 续集:白菜的内涵,更新nand分区为ubifs,替换overlay
在上一篇真千兆路由的极限之OPENWRT MAKE, 某品牌白菜价QCA9558/QCA9880/QCA8337N纯种组合OS搭建时记中附带了128M nand的空间图示,在ar71xx profil ...
- EasyUI combobox下拉列表实现搜索过滤(模糊匹配)
项目中的某个下拉列表长达200多个项,这么巨大的数量一个一个找眼镜都得看花,于是就得整了个搜索功能.看网上别人帖子有只能前缀匹配的方案,但只能前缀匹配的话用起来也不是很方便.于是就记录一下模糊匹配的方 ...
- oracle的开窗函数
原创 select * from (select province, commodity, sum(price), ROW_NUMBER() OVER(PARTITION BY province o ...
- JVM内存结构 VS Java内存模型 VS Java对象模型
前面几篇文章中, 系统的学习了下JVM内存结构.Java内存模型.Java对象模型, 但是发现自己还是对这三者的概念和区别比较模糊, 傻傻分不清楚.所以就有了这篇文章, 本文主要是对这三个技术点再做一 ...
- Filebeat6.3文档—Log input配置
Filebeat6.3文档-Log input配置 paths 日志加载的路径.例如加载某一子目录级别下面路径的日志:/var/log/*/*.log.这表示会去加载以.log结尾的/var/log下 ...
- Unity经典游戏教程之:合金弹头
版权声明: 本文原创发布于博客园"优梦创客"的博客空间(网址:http://www.cnblogs.com/raymondking123/)以及微信公众号"优梦创客&qu ...
- java中线程安全,线程死锁,线程通信快速入门
一:多线程安全问题 ###1 引入 /* * 多线程并发访问同一个数据资源 * 3个线程,对一个票资源,出售 */ public class ThreadDemo { public static vo ...
- 通过jmeter发送webservice接口请求
1.webservice接口地址:http://ip:port/...?wsdl 2.接口数据类型:<cuxGmiChukuRmaTrxV><salesrepId xmlns:xsi ...
- Java泛型使用的简单介绍
目录 一. 泛型是什么 二. 使用泛型有什么好处 三. 泛型类 四. 泛型接口 五. 泛型方法 六. 限定类型变量 七. 泛型通配符 7.1 上界通配符 7.2 下界通配符 7.3 无限定通配符 八. ...