P2486 [SDOI2011]染色

P2486 [SDOI2011]染色

题意:

在这里插入图片描述

题解:

与一般的树链剖分相比,不同点在于查询的不是路径上颜色的数量而是颜色段的数量
对于两个颜色段,112和221,两个颜色段数量都是2
如果合在一起颜色段的数量就是3,因为左边颜色段的右侧和右边颜色段的左侧是一样的颜色,合在一起后就成一段
所以本题其实就是将常规的区间求和改成这种特殊情况,在求完和的基础上,对左区间的最后一个颜色和右区间的第一个颜色进行判断,如果一样就减一

树剖中是把两点之间剖成了若干条链,所以我们还要解决不同的链之间的颜色重复问题,解决top[a]与fa[top[a]]颜色重复问题即可(如图)
在这里插入图片描述
总结一下:
就是判断所有接口处颜色是否一样

代码:

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
#define lid (id << 1)
#define rid (id << 1) | 1
using namespace std;
int read(){int out = 0,flag = 1;char c = getchar();while(c < '0' || c >'9'){if(c == '-')flag = -1;c = getchar();}while(c >= '0' && c <= '9'){out = out * 10 + c - '0';c = getchar();}return flag * out;}
const int maxn = 100019;
int num,na,nume,cnt;
int head[maxn];
struct Node{int v,nxt;
}E[maxn * 2];
void add(int u,int v){E[++nume].nxt = head[u];E[nume].v = v;head[u] = nume;}
int size[maxn],wson[maxn],dep[maxn],fa[maxn],top[maxn],pos[maxn],ori[maxn];
int col[maxn];
void dfs1(int id,int F){size[id] = 1;for(int i = head[id];i;i = E[i].nxt){int v = E[i].v;if(v == F)continue;dep[v] = dep[id] + 1;fa[v] = id;dfs1(v,id);size[id] += size[v];if(size[v] > size[wson[id]])wson[id] = v;}
}
void dfs2(int id,int TP){top[id] = TP;pos[id] = ++cnt;ori[cnt] = id;if(!wson[id])return ;dfs2(wson[id],TP);for(int i = head[id];i;i = E[i].nxt){int v = E[i].v;if(v == fa[id] || v == wson[id])continue;dfs2(v,v);}
}
int lc[maxn << 2];
int rc[maxn << 2];
struct sag_tree{int l,r;int sum,c;//区间颜色总数,叶子颜色int lazy;//儿子的颜色
}tree[maxn << 2];
void pushup(int id)
{tree[id].sum = tree[lid].sum + tree[rid].sum;if(rc[lid] == lc[rid])tree[id].sum -= 1;//如果连接处颜色一样,减一 lc[id] = lc[lid];rc[id] = rc[rid];
} 
void build(int id,int l,int r){tree[id].l = l;tree[id].r = r;if(l == r){tree[id].c = col[ori[l]];//赋值:叶子颜色lc[id] = rc[id] = col[ori[l]];//赋值:区间左颜色和区间右颜色tree[id].sum = 1;//颜色数为1return ;}int mid = l + r >> 1;build(lid,l,mid);build(rid,mid + 1,r);pushup(id);
}
void pushdown(int id){if(tree[id].lazy != 0 && tree[id].l != tree[id].r){int c = tree[id].lazy;tree[lid].lazy = tree[rid].lazy = c;//粉刷tree[lid].c = tree[rid].c = c;lc[lid] = rc[lid] = lc[rid] = rc[rid] = c;//更新左右tree[lid].sum = tree[rid].sum = 1;//粉刷完以后只有一种颜色了tree[id].lazy = 0;}
}
void update(int id,int c,int l,int r){pushdown(id);if(tree[id].l == l && tree[id].r == r){tree[id].c = c;//更新颜色 tree[id].lazy = c;tree[id].sum = 1;//此时区间内只有一种颜色  lc[id] = rc[id] = c;return ;}int mid = tree[id].l + tree[id].r >> 1;if(mid < l){update(rid,c,l,r);}else if(mid >= r){update(lid,c,l,r);}else{update(lid,c,l,mid);update(rid,c,mid + 1,r);}pushup(id);
}
int query(int id,int l,int r)//查询区间颜色数量 
{pushdown(id);if(tree[id].l == l && tree[id].r == r){return tree[id].sum;}int mid = tree[id].l + tree[id].r >> 1;if(mid < l){return query(rid,l,r);}else if(mid >= r){return query(lid,l,r);}else{int ret = query(lid,l,mid) + query(rid,mid + 1,r);if(rc[lid] == lc[rid])ret -= 1;//如果连接处颜色一样 return ret;}
}
int Qc(int id,int l,int r){//查询单点的颜色pushdown(id);if(tree[id].l == l && tree[id].r == r){return tree[id].c;}int mid = tree[id].l + tree[id].r >> 1;if(mid < l)return Qc(rid,l,r);else return Qc(lid,l,r);
}
void uprange(int x,int y,int c){while(top[x] != top[y]){if(dep[top[x]] < dep[top[y]])swap(x,y);update(1,c,pos[top[x]],pos[x]);x = fa[top[x]];}if(dep[x] > dep[y])swap(x,y);update(1,c,pos[x],pos[y]);
}
int Qsum(int x,int y){int ans = 0,Cson,Cfa;//儿子的颜色,爸爸的颜色while(top[x] != top[y]){if(dep[top[x]] < dep[top[y]])swap(x,y);ans += query(1,pos[top[x]],pos[x]);Cson = Qc(1,pos[top[x]],pos[top[x]]);Cfa = Qc(1,pos[fa[top[x]]],pos[fa[top[x]]]);if(Cson == Cfa)ans -= 1;x = fa[top[x]];}if(dep[x] > dep[y])swap(x,y);ans += query(1,pos[x],pos[y]);return ans;
}
int main(){num = read();na = read();for(int i = 1;i <= num;i++)col[i] = read();int u,v;for(int i = 1;i <= num - 1;i++){u = read();v = read();add(u,v);add(v,u);}dfs1(1,-1);dfs2(1,1);build(1,1,num);char ask;int c;for(int i = 1;i <= na;i++){cin>>ask;if(ask == 'Q'){u = read();v = read();printf("%d\n",Qsum(u,v));}else{u = read();v = read();c = read();uprange(u,v,c);}}return 0;}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/318194.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

牛客网CSP-S提高组赛前集训营1题解(仓鼠的石子游戏 [博弈论] + 乃爱与城市的拥挤程度 [树上DP] + 小w的魔术扑克[dfs + 离线])

文章目录T1&#xff1a;仓鼠的石子游戏题目题解代码实现T2&#xff1a;乃爱与城市拥挤程度题目题解代码实现T3&#xff1a;小w的魔术扑克题目题解代码实现T1&#xff1a;仓鼠的石子游戏 题目 仓鼠和兔子被禁止玩电脑&#xff0c;无聊的他们跑到一块空地上&#xff0c;空地上有…

使用PerfView监测.NET程序性能(二):Perfview的使用

在上一篇博客使用PerfView监测.NET程序性能&#xff08;一&#xff09;&#xff1a;Event Trace for Windows 中&#xff0c;我们了解了对Windows及应用程序进行性能分析的基础&#xff1a;Event Trace for Windows (ETW)。现在来看看基于ETW的性能分析工具——Perfview.exePer…

学习有向图和无向图的强连通分量(基本概念+割点+点双联通分量+桥+边双连通分量+全套模板【Tarjan】)

最近总是考到Tarjan&#xff0c;让我措手不及基本概念割点以及点双连通分量Tarjan法求割点推导过程代码实现Tarjan法求点双连通分量推导过程代码实现有向图的Tarjan缩点桥与边双连通分量Tarjan法求桥理论推导代码实现Tarjan法求边双连通分量理论推导代码实现前言&#xff1a;有…

.NET Core下的Spring Cloud——前言和概述

前言前几年一直在写类似dubbo&#xff0c;Spring Cloud的微服务框架辗辗转转重复了多次&#xff0c;也重构推翻了很多次&#xff0c;其中诞生了“Rabbit.Rpc”,”Go”,”RabbitCloud”等开源项目。其中不乏他人对这些项目的完善。很高兴自己的开源项目能够给他人提供思路和复用…

CF785E Anton and Permutation

CF785E Anton and Permutation 题意&#xff1a; 对于一个长度为 n 的序列进行 k 次操作&#xff0c;每次操作都是交换序列中的某两个数。对于每一个操作&#xff0c;回答当前序列中有多少个逆序对。 1<n<200000 1<q<50000 题解&#xff1a; 动态逆序对&#x…

[ NOIP提高组 2016]愤怒的小鸟(暴搜 + 状压DP)// [SNOI2017]一个简单的询问(莫队)

一次性写两道题T1&#xff1a;一个简单的询问题目题解代码实现T2&#xff1a;愤怒的小鸟题目暴搜题解暴搜代码实现状压DP题解状压DP代码实现T1&#xff1a;一个简单的询问 题目 给你一个长度为 N 的序列 ai ,1≤i≤N&#xff0c;和 q 组询问&#xff0c;每组询问读入 l1,r1,l…

微软发布新的 Azure Pipelines 功能和集成

在最近举行的Connect()大会上&#xff0c;微软发布了几项新功能以及与 Azure Pipelines 的集成&#xff0c;包括 Visual Studio Code 的 Azure Pipelines 扩展、GitHub 版本管理、对 IoT 项目的支持以及 ServiceNow 集成。自从 9 月份推出 Azure Pipelines 以来&#xff0c;这种…

年末展望:Oracle 对 JDK收费和.NET Core 给我们的机遇

2018年就结束了&#xff0c;马上就要迎来2019年&#xff0c;这一年很不平凡&#xff0c;中美贸易战还在继续&#xff0c;IT互联网发生急剧变化&#xff0c;大量互联网公司开始裁员&#xff0c;微软的市值在不断上升 &#xff0c;在互联网公司的市值下跌过程中爬到了第一的位置&…

等比数列三角形 (数论 + 黄金分割点)+ JOISC 2016 Day3 T3 「电报」(基环树 + 拓扑排序)

文章目录T1&#xff1a;等比数列三角形题目题解代码实现T2&#xff1a;电报题目题解代码实现T1&#xff1a;等比数列三角形 题目 求三边都是 ≤n 的整数&#xff0c;且成等比数列的三角形个数 注意三角形面积不能为 0 注意 oeis 中未收录此数列&#xff0c;所以并不需要去搜了…

使用PerfView监测.NET程序性能(三):分组

在上一篇博客使用PerfView监测.NET程序性能&#xff08;二&#xff09;&#xff1a;Perfview的使用中&#xff0c;我们通过Perfview帮助文件中自带的代码来简单使用了Perfview&#xff0c;了解了基本操作。现在来看看Perfview中的分组操作&#xff08;Grouping&#xff09;。分…

【做题记录】构造题

CF468C Hack it! 题意&#xff1a; 令 \(F(x)\) 表示 \(x\) 的各个位上的数字之和&#xff0c;如 \(F(1234)123410\) 。 给定 \(a(a\le 10^{18})\) &#xff0c;请求出任意一组 \(l,r(l,r\le 10^{200})\) &#xff0c;要求满足&#xff1a; \[\sum_{il}^{r}F(i)\pmod{a}0 \]输出…

Star Way To Heaven (prim最小生成树) // [ NOIP提高组 2014]飞扬的小鸟(DP)

文章目录T1&#xff1a;Star Way To Heaven题目题解代码实现T2&#xff1a;飞扬的小鸟题目题解代码实现T1&#xff1a;Star Way To Heaven 题目 小 w 伤心的走上了 Star way to heaven。 到天堂的道路是一个笛卡尔坐标系上一个 n*m 的长方形通道 顶点在 (0,0) 和 (n,m) 。 小…

IdentityServer4-客户端的授权模式原理分析(三)

在学习其他应用场景前&#xff0c;需要了解几个客户端的授权模式。首先了解下本节使用的几个名词Resource Owner&#xff1a;资源拥有者&#xff0c;文中称“user”&#xff1b;Client为第三方客户端&#xff1b;Authorization server为授权服务器&#xff1b;redirection URI&…

[2019 牛客CSP-S提高组赛前集训营4题解] 复读数组(数论)+ 路径计数机(数上DP)+ 排列计数机(线段树+二项式定理)

文章目录T1&#xff1a;复读数组题目题解代码实现T2&#xff1a;路径计数机题目题解代码实现T3&#xff1a;排列计数机题目题解CODET1&#xff1a;复读数组 题目 有一个长为nk的数组&#xff0c;它是由长为n的数组A1,A2,…,An重复k次得到的。 定义这个数组的一个区间的权值为…

微软携手 Docker 打造 CNAB,分布式应用来了!

微软中国MSDN 前天Microsoft Connect(); 2018发布的众多最新科技&#xff0c;都让全球开发者惊艳不已。其中一项最令开发者瞩目并迫不及待——微软联合Docker发布了云本地应用捆绑包&#xff08;Cloud Native Application Bundle&#xff0c;以下简称CNAB&#xff09;&#xff…

[C++]试一试结构体struct node的构造函数

可直接点击跳转到构造函数处结构体概念定义结构体定义结构体及结构体变量结构体变量的特点成员调用成员函数调用结构体的构造函数Upd1Upd2Upd3结构体概念 在实际问题中&#xff0c;一组数据往往具有不同的数据类型。 例如&#xff1a;人口大普查时&#xff0c;需要记录每一个人…

[多校联考-西南大学附中]切面包(线段树/概率与期望)+ Slow Path Finding Algorithm(拓扑排序/DP)+ 分数转化(数论)

文章目录T1&#xff1a;分数转换题目题解代码实现T2&#xff1a;Slow Path Finding Algorithm题目题解代码实现T3&#xff1a;切面包题目题解代码实现T1&#xff1a;分数转换 题目 Time limit: 1.5 seconds Memory limit: 512 megabytes 给定一个十进制小数&#xff0c;请你…

P3992 [BJOI2017]开车

P3992 [BJOI2017]开车 题意&#xff1a; 题解&#xff1a; 我们要先将问题转换 圈是车&#xff0c;x是加油站。红色部分为车移动的路线 数组a是车数量的前缀和 数组b是加油站的前缀和 而a[i]与b[i]的差的绝对值就是对应的红色路被走的次数 现在车发生位置移动&#xff0c;b数…

IdentityServer4-MVC+Hybrid实现Claims授权验证(四)

上节IdentityServer4-客户端的授权模式原理分析&#xff08;三&#xff09;以对话形式&#xff0c;大概说了几种客户端授权模式的原理&#xff0c;这节重点介绍Hybrid模式在MVC下的使用。且为实现IdentityServer4从数据库获取User进行验证&#xff0c;并对Claim进行权限设置打下…

漫谈何时从单体架构迁移到微服务?

面对微服务如火如荼的发展&#xff0c;很多人都在了解&#xff0c;学习希望能在自己的项目中帮得上忙&#xff0c;当你对微服务的庐山真面目有所了解后&#xff0c;接下来就是说服自己了&#xff0c;到底如何评估微服务&#xff0c;什么时候使用微服务&#xff0c;什么时间点最…