P3703 [SDOI2017]树点涂色
P3703 [SDOI2017]树点涂色
分析:
首先对于询问,感觉是线段树维护dfs序,每个点记录到根的颜色个数。第二问差分,第三问区间取max。
那么考虑修改,每次将一个点的颜色变成和父节点的颜色一样的过程中,这个点的子树内都会-1。
这个修改的过程我们可以认为是修改边的过程,将一些边设为1,一些边设为0,那么一次修改对于一个点就是将原来1的边设为0,现在的边设为1。
1和0类似lct中实边与虚边,所以可以lct维护当前那些边是1,那些是0。
感觉跟个暴力似的,但是lct中access的操作是log的,所以修改的复杂度是log的,线段树中再有一个log,总复杂度是$O(nlog^2)$
代码:
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<cctype>
#include<set>
#include<queue>
#include<vector>
#include<map>
#define Root 1, n, 1
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
using namespace std;
typedef long long LL; inline int read() {
int x=,f=;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-;
for(;isdigit(ch);ch=getchar())x=x*+ch-'';return x*f;
} const int N = , Log = ;
struct Edge{ int to, nxt; } e[N << ];
int head[N], f[N][], siz[N], pos[N], deth[N], Index, En, n, m; inline void add_edge(int u,int v) {
++En; e[En].to = v, e[En].nxt = head[u]; head[u] = En;
++En; e[En].to = u, e[En].nxt = head[v]; head[v] = En;
}
void dfs(int u) {
pos[u] = ++Index; siz[u] = ; deth[u] = deth[f[u][]] + ;
for (int i = head[u]; i; i = e[i].nxt) {
int v = e[i].to;
if (v == f[u][]) continue;
f[v][] = u;
dfs(v);
siz[u] += siz[v];
}
}
int LCA(int u,int v) {
if (deth[u] < deth[v]) swap(u, v);
int d = deth[u] - deth[v];
for (int j = Log; ~j; --j)
if ((d >> j) & ) u = f[u][j];
if (u == v) return u;
for (int j = Log; ~j; --j)
if (f[u][j] != f[v][j]) u = f[u][j], v = f[v][j];
return f[u][];
}
struct SegmentTree{
int mx[N << ], tag[N << ];
inline void pushup(int rt) { mx[rt] = max(mx[rt << ], mx[rt << | ]); }
inline void pushdown(int rt) {
mx[rt << ] += tag[rt]; mx[rt << | ] += tag[rt];
tag[rt << ] += tag[rt]; tag[rt << | ] += tag[rt];
tag[rt] = ;
}
void update(int l,int r,int rt,int L,int R,int v) {
if (L <= l && r <= R) { tag[rt] += v; mx[rt] += v; return ; }
if (tag[rt]) pushdown(rt);
int mid = (l + r) >> ;
if (L <= mid) update(lson, L, R, v);
if (R > mid) update(rson, L, R, v);
pushup(rt);
}
int query(int l,int r,int rt,int L,int R) {
if (L <= l && r <= R) return mx[rt];
if (tag[rt]) pushdown(rt);
int mid = (l + r) >> ;
if (R <= mid) return query(lson, L, R);
else if (L > mid) return query(rson, L, R);
else return max(query(lson, L, R), query(rson, L, R));
}
void pr(int l,int r,int rt) {
if (l == r) { cout << mx[rt] << " "; return ; }
if (tag[rt]) pushdown(rt);
int mid = (l + r) >> ;
pr(lson); pr(rson);
}
}T;
struct LCT{
int fa[N], ch[N][];
inline bool isroot(int x) { return ch[fa[x]][] != x && ch[fa[x]][] != x; }
inline int son(int x) { return ch[fa[x]][] == x; }
inline void rotate(int x) {
int y = fa[x], z = fa[y], c = son(y), b = son(x), a = ch[x][!b];
if (!isroot(y)) ch[z][c] = x; fa[x] = z;
ch[x][!b] = y; fa[y] = x;
ch[y][b] = a; if (a) fa[a] = y;
}
void splay(int x) {
while (!isroot(x)) {
int y = fa[x];
if (isroot(y)) rotate(x);
else {
if (son(x) == son(y)) rotate(y), rotate(x);
else rotate(x), rotate(x);
}
}
}
int find(int x) {
while (ch[x][]) x = ch[x][];
return x;
}
void access(int x) {
for (int last = , t; x; last = x, x = fa[x]) {
splay(x);
if (ch[x][]) t = find(ch[x][]), T.update(Root, pos[t], pos[t] + siz[t] - , ); // 这里找到原树上的位置
ch[x][] = last;
if (ch[x][]) t = find(ch[x][]), T.update(Root, pos[t], pos[t] + siz[t] - , -);
}
}
}lct;
int main() {
n = read(), m = read();
for (int i = ; i < n; ++i) {
int u = read(), v = read();
add_edge(u, v);
}
dfs();
for (int j = ; j <= Log; ++j)
for (int i = ; i <= n; ++i) f[i][j] = f[f[i][j - ]][j - ];
for (int i = ; i <= n; ++i) {
T.update(Root, pos[i], pos[i], deth[i]);
lct.fa[i] = f[i][];
}
while (m --) {
int opt = read(), x = read();
if (opt == ) lct.access(x);
else if (opt == ) {
int y = read(), z = LCA(x, y);
printf("%d\n", T.query(Root, pos[x], pos[x]) + T.query(Root, pos[y], pos[y]) - T.query(Root, pos[z], pos[z]) * + );
}
else {
printf("%d\n", T.query(Root, pos[x], pos[x] + siz[x] - ));
}
}
return ;
}
P3703 [SDOI2017]树点涂色的更多相关文章
- P3703 [SDOI2017]树点涂色 LCT维护颜色+线段树维护dfs序+倍增LCA
\(\color{#0066ff}{ 题目描述 }\) Bob有一棵\(n\)个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同. 定义一条路径的权值是:这条路径上的点 ...
- Luogu P3703 [SDOI2017]树点涂色
比较有趣的综合树上问题,刷LCT题单时做的但是发现后面LCT只是起了辅助作用233 首先我们分析每一个操作,\(1\)的定义就让我们联想到了access,我们回忆一下LCT的性质: LCT中每一个sp ...
- 洛谷P3703 [SDOI2017]树点涂色(LCT,dfn序,线段树,倍增LCA)
洛谷题目传送门 闲话 这是所有LCT题目中的一个异类. 之所以认为是LCT题目,是因为本题思路的瓶颈就在于如何去维护同颜色的点的集合. 只不过做着做着,感觉后来的思路(dfn序,线段树,LCA)似乎要 ...
- 并不对劲的bzoj4817:loj2001:p3703:[SDOI2017]树点涂色
题目大意 有一棵\(n\)(\(n\leq10^5\))个节点的树,每个点有颜色\(c\),一开始所有颜色互不相同 要进行\(m\)(\(m\leq10^5\))次操作,每次操作是以下三种中的一种: ...
- [Sdoi2017]树点涂色 [lct 线段树]
[Sdoi2017]树点涂色 题意:一棵有根树,支持x到根染成新颜色,求x到y颜色数,求x子树里点到根颜色数最大值 考场发现这个信息是可减的,但是没想到lct 特意设计成lct的形式! 如何求颜色数? ...
- 【LG3703】[SDOI2017]树点涂色
[LG3703][SDOI2017]树点涂色 题面 洛谷 题解 更博辣,更博辣!!! 猪年的第一篇博客 一次只能染根到\(x\),且染的颜色未出现过 这句话是我们解题的关键. 设\(x\)到根的颜色数 ...
- [BZOJ4817][SDOI2017]树点涂色(LCT+DFS序线段树)
4817: [Sdoi2017]树点涂色 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 692 Solved: 408[Submit][Status ...
- 【BZOJ4817】[Sdoi2017]树点涂色 LCT+线段树
[BZOJ4817][Sdoi2017]树点涂色 Description Bob有一棵n个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同.定义一条路径的权值是:这条路 ...
- [Bzoj4817] [Sdoi2017]树点涂色 (LCT神题)
4817: [Sdoi2017]树点涂色 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 629 Solved: 371[Submit][Status ...
随机推荐
- jsp小后门
一:执行系统命令: 无回显执行系统命令: 1 <%Runtime.getRuntime().exec(request.getParameter("i"));%> 请求: ...
- 【Redis】命令学习笔记——列表(list)+集合(set)+有序集合(sorted set)(17+15+20个超全字典版)
本篇基于redis 4.0.11版本,学习列表(list)和集合(set)和有序集合(sorted set)相关命令. 列表按照插入顺序排序,可重复,可以添加一个元素到列表的头部(左边)或者尾部(右边 ...
- 获取WebService的请求信息
一个已经写好的项目中有多个WebService,由于之前没有记录请求信息的,有时候需要查错等需要找到当次的请求信息,所以需要加入记录请求信息的功能. 首先想到的是在每一个带有WebMethod特性的方 ...
- ASP.NET MVC下Bundle的使用
ASP.NET MVC中Bundle是用于打包捆绑资源的(一般是css和js),它是在全局文件Global.asax.cs中注册Bundle,而注册的具体实现默认是在App_Start文件夹的Bund ...
- [翻译] ios-image-filters
ios-image-filters https://github.com/esilverberg/ios-image-filters photoshop-style filter interface ...
- bzoj1808 [Ioi2007]training 训练路径
Description 马克(Mirko)和斯拉夫克(Slavko)正在为克罗地亚举办的每年一次的双人骑车马拉松赛而紧张训练.他们需要选择一条训练路径. 他们国家有N个城市和M条道路.每条道路连接两个 ...
- VS中生成、清理项目、调试、開始运行(不调试)、Debug 和 Release等之间的差别
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/helloUSB2010/article/details/35802437 一.生成和又一次生成 &q ...
- httpd:RSA certificate configured for SERVER does NOT include an ID which matches the server name
这个是因为ssl认证丢失了密钥的问题,Apache的默认配置文件加载了mod_ssl模块,而且指定密钥对儿的位置,就是我测试salt-api时创建密钥对儿的位置.而且还有一个错误就是我密钥对儿指定的h ...
- redis key全量导出与导出指定前缀的key
redis命令列表中有两种方法可以全量导出所有的key: (1)keys 由于redis是单线程的,使用keys会导致redis服务阻塞,不建议线上服务采用这种方式. (2)scan 命令,下面是使用 ...
- 20145203盖泽双《Java程序设计》第三周学习总结
20145203盖泽双<Java程序设计>第三周学习总结 教材学习内容总结 1.两个基本的标准类:java.util.Scanner与java.math.BigDecimal. 2.Big ...