【线段树】【LCT】【LCA】树点涂色(luogu 3703)

树点涂色

luogu 3703

题目大意

给出一棵树,每个节点的初始颜色不同,做若干操作:
1.在一个点到根节点路径上染上一种新的颜色
2.查询一条路径上有多少种不同的颜色
3.查询一个点x,使该点到根节点路径的不同颜色种数最多

输入样例

5 6
1 2
2 3
3 4
3 5
2 4 5
3 3
1 4
2 4 5
1 5
2 4 5

输出样例

3
4
2
2

数据范围

1⩽n,m⩽1051\leqslant n,m\leqslant 10^51n,m105

解题思路

对于该图,可以建立LCT,虚边连接的是不同颜色的点,实边连接的是相同颜色的点,然后对此进行操作
操作1和access操作相似
对于修改一个点x的颜色
对于修改链中的点,本来x贡献为1,修改后为0,所以修改链深度大于y的p-1
而对于x原来所在链上的点,本来x贡献为0,修改后为1,所以该链上深度大于y的p+1
操作2相当于x点到lca的不同颜色种数加上y点到lca的不同颜色种数
就是px+py−2×plca+1p_x+p_y-2\times p_{lca}+1px+py2×plca+1
操作3可以按dfs序建立线段树,这样就可以查询子树内的最小值了

代码

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
#define N 100010
using namespace std;
int n, m, x, y, z, w, tot, s[N<<2], fa[N], bg[N], ed[N], dep[N], lazy[N<<2], head[N], son[N][2], faa[N][20];
struct rec
{int to, next;
}a[N<<1];
void add(int x, int y)
{a[++tot].to = y;a[tot].next = head[x];head[x] = tot;return; 
}
void downtate(int x)//线段树
{if (!lazy[x]) return;s[x * 2] += lazy[x], lazy[x * 2] += lazy[x];s[x * 2 + 1] += lazy[x], lazy[x * 2 + 1] += lazy[x];lazy[x] = 0;return;
}
void up(int x)
{s[x] = max(s[x * 2], s[x * 2 + 1]);return;
}
void change(int x, int L, int R, int l, int r, int y)
{if (L == l && R == r){s[x] += y;lazy[x] += y;return;}downtate(x);int mid = (L + R) >> 1;if (r <= mid) change(x * 2, L, mid, l, r, y);else if (l > mid) change(x * 2 + 1, mid + 1, R, l, r, y);else change(x * 2, L, mid, l, mid, y), change(x * 2 + 1, mid + 1, R, mid + 1, r, y);up(x);return;
}
int ask(int x, int L, int R, int l, int r)
{if (L == l && R == r) return s[x];int mid = (L + R) >> 1;downtate(x);if (r <= mid) return ask(x * 2, L, mid, l, r);else if (l > mid) return ask(x * 2 + 1, mid + 1, R, l, r);else return max(ask(x * 2, L, mid, l, mid), ask(x * 2 + 1, mid + 1, R, mid + 1, r));
}
bool NR(int x)//LCT
{return son[fa[x]][0] == x || son[fa[x]][1] == x;
}
bool IRS(int x)
{return son[fa[x]][1] == x;
}
void rotate(int x)
{int y = fa[x], z = fa[y], k = IRS(x), g = son[x][!k];if (NR(y)) son[z][IRS(y)] = x;if (g) fa[g] = y;son[x][!k] = y;son[y][k] = g;fa[x] = z;fa[y] = x;return;
}
void Splay(int x)
{while(NR(x)){if (NR(fa[x])) rotate(IRS(x) == IRS(fa[x]) ? fa[x] : x);rotate(x);}return;
}
int find_root(int x)
{while(son[x][0]) x = son[x][0];return x;
}
void access(int x)
{for (int y = 0; x; x = fa[y = x]){Splay(x);int z = son[x][1];if (z) z = find_root(z), change(1, 1, n, bg[z], ed[z], 1);//对原链上的点贡献+1if (y) z = find_root(y), change(1, 1, n, bg[z], ed[z], -1);//对修改的脸上的点贡献-1son[x][1] = y;}return;
}
void dfs(int x)//求dfs序
{bg[x] = ++w;dep[x] = dep[fa[x]] + 1;change(1, 1, n, bg[x], bg[x], dep[x]);for (int i = 1; i <= 16; ++i)faa[x][i] = faa[faa[x][i - 1]][i - 1];for (int i = head[x]; i; i = a[i].next)if (!bg[a[i].to]){faa[a[i].to][0] = fa[a[i].to] = x;dfs(a[i].to);}ed[x] = w;
}
int lca(int x, int y)
{if (dep[x] < dep[y]) swap(x, y);for (int i = 16; i >= 0; --i)if (dep[faa[x][i]] >= dep[y]) x = faa[x][i];for (int i = 16; i >= 0; --i)if (faa[x][i] != faa[y][i]) x = faa[x][i], y = faa[y][i];return x == y ? x : faa[x][0];
}
int main()
{scanf("%d%d", &n, &m);for (int i = 1; i < n; ++i){scanf("%d%d", &x, &y);add(x, y);add(y, x);}dfs(1);while(m--){scanf("%d", &x);if (x == 1){scanf("%d", &x);access(x);}else if (x == 2){scanf("%d%d", &x, &y);z = lca(x, y);x = ask(1, 1, n, bg[x], bg[x]);y = ask(1, 1, n, bg[y], bg[y]);z = ask(1, 1, n, bg[z], bg[z]);printf("%d\n", x + y - z * 2 + 1);}else{scanf("%d", &x);printf("%d\n", ask(1, 1, n, bg[x], ed[x]));}}return 0;
}

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

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

相关文章

P3515-[POI2011]Lightning Conductor【整体二分,决策单调性】

正题 题目链接:https://www.luogu.com.cn/problem/P3507 题目大意 nnn个数字的一个序列aaa&#xff0c;对于每个位置iii求一个pip_ipi​使得对于任意jjj满足 piai−∣i−j∣≥pjp_ia_i-\sqrt{|i-j|}\geq p_jpi​ai​−∣i−j∣​≥pj​ 解题思路 化简一下发现我们是需要求出m…

关于二项式

组合数 (nm)\dbinom{n}{m}(mn​)&#xff1a;从 nnn 个物品中选出 mmm 个的方案数。 (nm)n!m!(n−m)!nm‾m!\dbinom{n}{m}\dfrac{n!}{m!(n-m)!}\dfrac{n^{\underline{m}}}{m!}(mn​)m!(n−m)!n!​m!nm​​ &#xff08;这个式子只依靠经典的组合意义&#xff0c;所以只在 0≤m≤…

dotnet core高吞吐Http api服务组件FastHttpApi

简介是dotNet core下基于Beetlex实现的一个高度精简化和高吞吐的HTTP API服务开源组件&#xff0c;它并没有完全实现HTTP SERVER的所有功能&#xff0c;而是只实现了在APP和WEB中提供数据服务最常用两个指令GET/SET&#xff0c;满足在应用实现JSON,PROTOBUF和MSGPACK等基于HTTP…

Poj 1284 Primitive Roots

文章目录Description题意&#xff1a;题解&#xff1a;代码&#xff1a;Poj 1284Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 6485 Accepted: 3697Description We say that integer x, 0 < x < p, is a primitive root modulo odd prime p if and onl…

P3507-[POI2010]GRA-The Minima Game【dp,博弈论】

正题 题目链接:https://www.luogu.com.cn/problem/P3507 题目大意 nnn个数&#xff0c;没人轮流取若干个并获得取走的数中最小数的权值&#xff0c;两人的目标都是自己的权值−-−对方的权值最大&#xff0c;求先手的权值−-−后手的权值。 解题思路 肯定是从大往小取&#x…

【LCT】【树状数组】Matches Are Not a Child‘s Play(luogu CF1137F)

正题 luogu CF1137F 题目大意 定义一棵树的产出序列为依次删除权值最小的叶子节点的顺序 进行q此操作&#xff1a; 1.把一个点的权值改为当前树中的最大权值1 2.查询一个点在删除序列中的位置 3.给出两个点&#xff0c;查询哪个在删除序列中的位置更前 解题思路 假设已经求出…

[XSY4220] 九万步(结论)

手动构造发现 x6x6x6 时是可行的 -101234567xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

一起开心2020暑假训练第一周

hdu 1576 A/B oj传送 题解&#xff1a; Poj 1061 青蛙的约会 oj传送 题解&#xff1a; hdu 1525 Euclid‘s Game oj传送 题解&#xff1a; Poj 3070 Fibonacci oj传送 题解&#xff1a; HDU 2504 又见GCD oj传送 题解&#xff1a; Poj 1284 Primitive Roots oj传送 …

ASP.NET Core 中的中间件

前言由于是第一次写博客,如果您看到此文章,希望大家抱着找错误、批判的心态来看。 sky!何为中间件?在 ASP.NET Framework 中应该都知道请求管道。可参考&#xff1a;浅谈 ASP.NET 的内部机制 系列&#xff0c;个人感觉超详细。题外话&#xff1a;说到请求管道&#xff0c;就想…

【bfs】重力球(luogu 7473/NOI Online 2021 普及组 T3)

正题 luogu 7473 题目大意 给出一个正方形区域&#xff0c;中间有一些障碍 现在有两个球&#xff0c;每次操作可以使两个球同时向一个方向移动&#xff0c;直到遇到障碍或边界 现在问你让两个球到同一个位置最少要多少步 解题思路 对于每次操作&#xff0c;球只有可能停在障…

CF700E-Cool Slogans【SAM,线段树合并,dp】

正题 题目链接:https://www.luogu.com.cn/problem/CF700E 题目大意 给出一个字符串SSS&#xff0c;求一个最大的kkk使得存在kkk个字符串其中s1s_1s1​是SSS的子串&#xff0c;si1s_{i1}si1​在sis_isi​中出现了至少222次。 解题思路 首先我们需要有两个结论 si1s_{i1}si1​…

[XXSY] 构树(prufer序列,树上连通块DP)

传送门 CayleyCayleyCayley公式&#xff1a;一个完全图有nn−2n^{n-2}nn−2棵无根生成树&#xff08;可用prufer序列证明&#xff09; 扩展CayleyCayleyCayley公式&#xff1a;被确定边分为大小为a1,a2,⋯,ama_1,a_2,\cdots, a_ma1​,a2​,⋯,am​的连通块&#xff0c;则有nm−…

.NET Core中的性能测试工具BenchmarkDotnet

背景介绍之前一篇博客中&#xff0c;我们讲解.NET Core中的CSV解析库&#xff0c;在文章的最后&#xff0c;作者使用了性能基准测试工具BenchmarkDotNet测试了2个不同CSV解析库的性能&#xff0c;本篇我们来详细介绍一下BenchmarkDotNet。原文链接&#xff1a;https://dotnetco…

序列求和

来源&#xff1a;牛客网 文章目录题目描述题解&#xff1a;代码&#xff1a;时间限制&#xff1a;C/C 1秒&#xff0c;其他语言2秒 空间限制&#xff1a;C/C 131072K&#xff0c;其他语言262144K 64bit IO Format: %lld题目描述 定义S(n) 12 22 … n2&#xff0c;输出S(n) …

【区间DP】摆渡线路(2017 特长生 T4)

题目大意 给出一个园&#xff0c;圆上有100个点&#xff0c;若干条弦&#xff0c;让你选择尽量多互不相交的弦&#xff08;点可以重合&#xff09; 解题思路 可以把圆展开成链&#xff0c;然后复制一遍 设fi,jf_{i,j}fi,j​为第i个位置到第j个位置的所选弦的数量 那么可以枚…

bzoj4589-Hard Nim【FWT】

正题 题目链接:https://darkbzoj.tk/problem/4589 题目大意 求有多少个长度为nnn的数列满足它们都是不大于mmm的质数且异或和为000。 解题思路 两个初始多项式F[0]1F[0]1F[0]1&#xff0c;G[prime≤m]1G[prime\leq m]1G[prime≤m]1&#xff0c;然后答案就是FxorGnF\ xor\ G^…

some useful tricks

异或题思考方向&#xff1a;01trie树&#xff0c;分治 2. 二分图最大匹配&#xff0c;最大独立集互相转换 3. Snow 4. Code 5. Code 6. Code 7. 题目 #include<iostream> #include<cstdio> using namespace std; const int N100010; int n,p,nxt[N],no[200]…

25大技术主题向您发出最后一次约【惠】邀请

一年一度的微软技术盛会即将在上海世博中心拉开大幕金秋十月&#xff0c;来自两岸三地的百名明星讲师将携 25 大技术主题&#xff0c;齐聚上海为您奉献一场无与伦比的技术视听盛宴您&#xff0c;准备好了吗&#xff1f;25大技术主题公开&#xff0c;不负期待姗姗来迟的5系25大技…

P4980-[模板]Pólya定理

正题 题目链接:https://www.luogu.com.cn/problem/P4980 题目大意 nnn个物品图上mmm种颜色&#xff0c;求在可以旋转的情况下本质不同的涂色方案。 解题思路 既然是群论基本题就顺便写一下刚刚了解到的相关知识把&#xff08;顺便消磨一下时间 一个群(G,)(G,\times )(G,)定义…

逆元的求法

逆元&#xff1a; 对于a和p&#xff0c;若 a * inv(a) % p ≡ 1&#xff0c;则称inv(a)为a%p的逆元。其中p为质数 逆元就是在mod下&#xff0c;不能直接除以一个数&#xff0c;而要乘以他的逆元 a * inv(a) 1 (mod p) x / a可以改成 x * inv(a) % p 文章目录方法一.扩展欧几里…