【洛谷 P4116】 Qtree3 (树链剖分)
题目链接
树剖练手题,想复习下树剖。
第一次提交\(T\)成QQC
看我
???
看了数据范围的确挺恶心的,我的复杂度是\(O(Mlog^2N)\)的,数据范围有三段
For 1/3 of the test cases, N=5000, Q=400000.
For 1/3 of the test cases, N=10000, Q=300000.
For 1/3 of the test cases, N=100000, Q=100000.
很极限就对了。难道是我常数太大了?那也不至于只对\(3\)个点吧。
我看了一下,原来我求\(size\)的时候没有加上子树的\(size\)...这样就会剖出假的重链。
我加上去,再交,还是\(T\)成QQC。
看我
......
原来是标记\(top\)的时候错了。改过来就\(A\)了。
虽然有两个细节错误,但是没有别的错误,也就是说我树剖大致模板和线段树都是一次写对的。。
话不多说。
树剖后用线段树来维护,维护最小值,黑点的值为\(dfs\)序,白点的值为\(INF\),每次查询找到链上的最小值即为答案。
因为从\(1\)到\(x\)是一条直链,越上的点也就是越靠近\(1\)的点,\(dfs\)序一定最小。
#include <cstdio>
#define INF 2147483647
#define re register
int s; char ch;
inline int read(){
s = 0; ch = getchar();
while(ch < '0' || ch > '9') ch = getchar();
while(ch >= '0' && ch <= '9'){ s = s * 10 + ch - '0'; ch = getchar(); }
return s;
}
inline int min(int a, int b){
return a > b ? b : a;
}
const int MAXN = 100010;
struct Edge{
int next, to;
}e[MAXN << 1];
int head[MAXN], num, n, m, a, b, w[MAXN];
inline void Add(int from, int to){
e[++num].to = to; e[num].next = head[from]; head[from] = num;
e[++num].to = from; e[num].next = head[to]; head[to] = num;
}
int dep[MAXN], size[MAXN], maxson[MAXN], top[MAXN], ID, dfn[MAXN], pos[MAXN], f[MAXN];
namespace SegTree{
#define left (now << 1)
#define right (now << 1 | 1)
int Min[MAXN << 2];
inline void pushup(int now){
Min[now] = min(Min[left], Min[right]);
}
void build(int now, int l, int r){
if(l == r){ Min[now] = INF; return; }
int mid = (l + r) >> 1;
build(left, l, mid);
build(right, mid + 1, r);
pushup(now);
}
void update(int now, int l, int r, int x){
if(l == r){ Min[now] = (w[pos[x]] ? x : INF); return; }
int mid = (l + r) >> 1;
if(x <= mid) update(left, l, mid, x);
else update(right, mid + 1, r, x);
pushup(now);
}
int query(int now, int l, int r, int wl, int wr){
if(l > wr || r < wl) return INF;
if(l >= wl && r <= wr) return Min[now];
int ans = INF, mid = (l + r) >> 1;
ans = min(ans, query(left, l, mid, wl, wr));
ans = min(ans, query(right, mid + 1, r, wl, wr));
return ans;
}
}using namespace SegTree;
void dfs1(int u, int fa){
size[u] = 1; f[u] = fa;
for(re int i = head[u]; i; i = e[i].next)
if(e[i].to != fa){
dfs1(e[i].to, u);
size[u] += size[e[i].to];
if(size[e[i].to] > size[maxson[u]])
maxson[u] = e[i].to;
}
}
void dfs2(int u, int rt){
dfn[u] = ++ID; pos[ID] = u; top[u] = rt;
if(maxson[u]) dfs2(maxson[u], rt);
for(re int i = head[u]; i; i = e[i].next)
if(e[i].to != f[u] && e[i].to != maxson[u])
dfs2(e[i].to, e[i].to);
}
inline int solve(int u){
int ans = INF;
while(top[u] != 1){
ans = min(ans, query(1, 1, n, dfn[top[u]], dfn[u]));
u = f[top[u]];
}
ans = min(ans, query(1, 1, n, dfn[1], dfn[u]));
return ans == INF ? -1 : pos[ans];
}
int main(){
n = read(); m = read();
for(re int i = 1; i < n; ++i)
Add(read(), read());
dfs1(1, 0);
dfs2(1, 1);
build(1, 1, n);
for(re int i = 1; i <= m; ++i){
a = read(); b = read();
if(!a){
w[b] ^= 1;
update(1, 1, n, dfn[b]);
}
else printf("%d\n", solve(b));
}
return 0;
}
【洛谷 P4116】 Qtree3 (树链剖分)的更多相关文章
- 洛谷P3979 遥远的国度 树链剖分+分类讨论
题意:给出一棵树,这棵树每个点有权值,然后有3种操作.操作一:修改树根为rt,操作二:修改u到v路径上点权值为w,操作三:询问以rt为根x子树的最小权值. 解法:如果没有修改树根操作那么这题就是树链剖 ...
- 洛谷 P4114 Qtree1 树链剖分
目录 题面 题目链接 题目描述 输入输出格式 输入格式: 输出格式: 输入输出样例 输入样例: 输出样例: 说明 说明 思路 Change Query AC代码 总结 题面 题目链接 P4114 Qt ...
- [洛谷P3384] [模板] 树链剖分
题目传送门 显然是一道模板题. 然而索引出现了错误,狂wa不止. 感谢神犇Dr_J指正.%%%orz. 建线段树的时候,第44行. 把sum[p]=bv[pos[l]]%mod;打成了sum[p]=b ...
- 洛谷.4114.Qtree1(树链剖分)
题目链接 模板题都错了这么多次.. //边权赋到点上 树剖模板 //注意LCA.链的顶端不能统计到答案! #include <cstdio> #include <cctype> ...
- 洛谷3384&bzoj1036树链剖分
值得注意的是: 一个点的子树是存在一起的...也就是说我们修改子树的时候只用... /********************************************************* ...
- 洛谷P4116 Qtree3
题目描述 给出\(N\)个点的一棵树(\(N-1\)条边),节点有白有黑,初始全为白 有两种操作: \(0\) \(i\) : 改变某点的颜色(原来是黑的变白,原来是白的变黑) \(1\) \(v\) ...
- 洛谷P4116 Qtree3(树剖+线段树)
传送门 LCT秒天秒地 树剖比较裸的题了 用线段树记录一下区间的最左边的黑点的编号(因为同一条链上肯定是最左边的深度最小,到根节点距离最近) 然后记得树剖的时候肯定是越后面的答案越优,因为深度越浅 / ...
- 洛谷 P4116 Qtree3
Qtree系列第三题 我是题面 读完题大概不难判断是一道树剖的题 这道题的关键是记录两种状态,以及黑点的序号(不是编号) 线段树啊当然 定义两个变量v,f,v表示距离根节点最近的黑点,默认-1,f则表 ...
- Qtree3 - 树链剖分
打完以后才发现写复杂了……算了懒得改了 #include <bits/stdc++.h> using namespace std; ],fa[][],size[],wson[],vis[] ...
- 洛谷 P3384 【模板】树链剖分
树链剖分 将一棵树的每个节点到它所有子节点中子树和(所包含的点的个数)最大的那个子节点的这条边标记为"重边". 将其他的边标记为"轻边". 若果一个非根节点的子 ...
随机推荐
- LintCode-212.空格替换
空格替换 设计一种方法,将一个字符串中的所有空格替换成 %20 .你可以假设该字符串有足够的空间来加入新的字符,且你得到的是"真实的"字符长度. 你的程序还需要返回被替换后的字符串 ...
- iOS APP中第三方APP调用自己的APP,打开文件
根据需求需要在项目中要打开word.pdf.excel等文件,在info.plist文件中添加 <key>CFBundleDocumentTypes</key> <arr ...
- JVM启动参数详解 (转)
非标准参数 非标准参数又称为扩展参数,其列表如下: -Xint 设置jvm以解释模式运行,所有的字节码将被直接执行,而不会编译成本地码. -Xbatch 关闭后台代码编译,强制在前台编译,编译 ...
- 【bzoj5064】B-number 数位dp
题目描述 B数的定义:能被13整除且本身包含字符串"13"的数. 例如:130和2613是B数,但是143和2639不是B数. 你的任务是计算1到n之间有多少个数是B数. 输入 输 ...
- 关于"作数类型冲突: nvarchar 与 image 不兼容"的问题
数据库如果是Image类型,当执行插入语句时,如果插入的值是DBNull.Value时提示:操作数类型冲突: nvarchar 与 image 不兼容; 出现这个问题的原因是没有指定DbType的原因 ...
- P1955 [NOI2015]程序自动分析
题目描述 在实现程序自动分析的过程中,常常需要判定一些约束条件是否能被同时满足. 考虑一个约束满足问题的简化版本:假设x1,x2,x3...代表程序中出现的变量,给定n个形如xi=xj或xi≠xj的变 ...
- IntellIJ IDEA 配置 Maven
一.配置Maven环境 1.下载apache-maven文件,选择自己需要的版本 2.解压1所下载文件,E:\apache-maven-3.5.4 3.配置Maven环境变量 a. MAVEN_HOM ...
- [JSOI2007]重要的城市 floyd:最短路计数
---题面--- 题解: 其实感觉还是比较妙的,第一眼看题想到floyd统计最短路条数, 注意到对于任意两点x,y而言,floyd将会枚举其最短路所可能经过的所有中转点, 因此我们可以直接分别统计对于 ...
- BZOJ1047:[HAOI2007]理想的正方形——题解
http://www.lydsy.com/JudgeOnline/problem.php?id=1047 https://www.luogu.org/problemnew/show/P2216#sub ...
- 洛谷 P1841 [JSOI2007]重要的城市 解题报告
P1841 [JSOI2007]重要的城市 题目描述 参加jsoi冬令营的同学最近发现,由于南航校内修路截断了原来通向计算中心的路,导致去的路程比原先增加了近一公里.而食堂门前施工虽然也截断了原来通向 ...