Qtree3题解(树链剖分(伪)+线段树+set)
外话:最近洛谷加了好多好题啊...原题入口 这题好像是SPOJ的题,挺不错的。看没有题解还是来一篇...
题意
很易懂吧。。
题解
我的做法十分的暴力:树链剖分(伪)+线段树+ std :: set
...
首先,我们可以考虑每次修改一个点的颜色的影响。
易知,翻转一个点颜色,只会对于他的子树产生影响,对于别的点就毫无意义了。
然后,只要学过一点树链剖分的就知道,我们可以将整棵树按它的\(dfs\)序进行标号,
每个点的序号就是\(dfn\),
然后记下它的子树大小\(size\),然后对于每个点\(u\)所在的子树区间就是\([dfn[u], dfn[u]+size[u]-1]\)。
所以每次操作的时候,只要对于那一段区间进行修改就行了。
然后我们要修改和查询什么呢?不就是查询包含这个点,且深度最小的黑点吗?(需要把\(1\)作为根)
所以,我们每次记下一个区间中,包含这个点的所有黑色标号以及他们的深度,用\(pair\)记录一下(因为这个可以
自动按照第一关键字排序),再用\(set\)维护一下区间最值就行了。
每次更新的时候只要在\(set\)里面\(insert\)和\(erase\)。
查询就是从根节点一直向下跑,不断取一个深度更小的\(ans\)。
具体有些实现在程序中会体现的……
总时间复杂度\(O(q \log \ n \log q)\) 空间复杂度也是\(O(q \log \ n \log \ q)\)。(所以说很暴力嘛……)
代码
#include <bits/stdc++.h>
#define For(i, l, r) for(int i = (l), _end_ = (int)(r); i <= _end_; ++i)
#define Fordown(i, r, l) for(int i = (r), _end_ = (int)(l); i >= _end_; --i)
#define Set(a, v) memset(a, v, sizeof(a))
using namespace std;
bool chkmin(int &a, int b) {return b < a ? a = b, 1 : 0;}
bool chkmax(int &a, int b) {return b > a ? a = b, 1 : 0;}
inline int read() {
int x = 0, fh = 1; char ch = getchar();
for (; !isdigit(ch); ch = getchar() ) if (ch == '-') fh = -1;
for (; isdigit(ch); ch = getchar() ) x = (x<<1) + (x<<3) + (ch ^ '0');
return x * fh;
}
void File() {
#ifdef zjp_shadow
freopen ("P4116.in", "r", stdin);
freopen ("P4116.out", "w", stdout);
#endif
}
const int N = 1e5 + 1e3, M = N << 1;
int n, q;
int sz[N], dfn[N], dep[N];
int to[M], Next[M], Head[N], e = 0;
void add(int u, int v) {
to[++e] = v;
Next[e] = Head[u];
Head[u] = e;
}
void Dfs(int u, int fa) {
static int clk = 0;
sz[u] = 1;
dfn[u] = ++ clk;
dep[u] = dep[fa] + 1;
for (register int i = Head[u]; i; i = Next[i]) {
register int v = to[i];
if (v == fa) continue ;
Dfs(v, u); sz[u] += sz[v];
}
}//就是树链剖分的第一个dfs,求出size,dep,dfn
typedef pair<int, int> PII;
#define mp make_pair
#define lson o << 1, l, mid
#define rson o << 1 | 1, mid + 1, r
set<PII> S[N << 2];
bool col[N];//因为不知道是变啥颜色,所以要记一下原来的颜色
bool uopt; int ul, ur; PII uv;
void Update(int o, int l, int r) {
if (ul <= l && r <= ur) {
if (uopt) S[o].erase(uv);
else S[o].insert(uv);
//erase可以直接调用那个值.
return ;
}
int mid = (l + r) >> 1;
if (ul <= mid) Update(lson);
if (ur > mid) Update(rson);
}
PII ans; int up;
void Query(int o, int l, int r) {
if ((bool)S[o].size() )
ans = min(ans, *S[o].begin() );
//begin就是这个set中最小的那一个,即这里面深度最小的那个点
if (l == r) return ;
int mid = (l + r) >> 1;
if (up <= mid) Query(lson);
else Query(rson);
}
const int inf = 0x3f3f3f3f;
int main () {
n = read(); q = read();
For (i, 1, n - 1) {
int u, v;
scanf ("%d%d", &u, &v);
//int u = read(), v = read();
add(u, v); add(v, u);
}
Dfs(1, 0);
For (i, 1, q) {
int opt, pos;
scanf ("%d%d", &opt, &pos);
//int opt = read(), pos = read();
if (opt == 0) {
uopt = col[pos];
col[pos] ^= true;
ul = dfn[pos];
ur = dfn[pos] + sz[pos] - 1;
uv = mp(dep[pos], pos);
Update(1, 1, n);
} else {
ans = mp(inf, inf);
up = dfn[pos];
Query(1, 1, n);
printf ("%d\n", ans.second == inf ? -1 : ans.second);
}
}
//cerr << clock() << endl;
return 0;
}
后记:看到很多dalao都是用啥 主席树,倍增,和不用\(set\)的线段树做过去的。跑得都比我快,希望后面有人能讲一讲QAQ。
Qtree3题解(树链剖分(伪)+线段树+set)的更多相关文章
- HDU 4366 Successor(树链剖分+zkw线段树+扫描线)
[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=4366 [题目大意] 有一个公司,每个员工都有一个上司,所有的人呈树状关系,现在给出每个人的忠诚值和 ...
- 【BZOJ3531】旅行(树链剖分,线段树)
[BZOJ3531]旅行(树链剖分,线段树) 题面 Description S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足 从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教 ...
- 【BZOJ5507】[GXOI/GZOI2019]旧词(树链剖分,线段树)
[BZOJ5507][GXOI/GZOI2019]旧词(树链剖分,线段树) 题面 BZOJ 洛谷 题解 如果\(k=1\)就是链并裸题了... 其实\(k>1\)发现还是可以用类似链并的思想,这 ...
- 【洛谷5439】【XR-2】永恒(树链剖分,线段树)
[洛谷5439][XR-2]永恒(树链剖分,线段树) 题面 洛谷 题解 首先两个点的\(LCP\)就是\(Trie\)树上的\(LCA\)的深度. 考虑一对点的贡献,如果这两个点不具有祖先关系,那么这 ...
- bzoj 4034 [HAOI2015] T2(树链剖分,线段树)
4034: [HAOI2015]T2 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 1536 Solved: 508[Submit][Status] ...
- bzoj 1036 [ZJOI2008]树的统计Count(树链剖分,线段树)
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 10677 Solved: 4313[Submit ...
- poj 3237 Tree(树链剖分,线段树)
Tree Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 7268 Accepted: 1969 Description ...
- bzoj 3626 [LNOI2014]LCA(离线处理+树链剖分,线段树)
3626: [LNOI2014]LCA Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1272 Solved: 451[Submit][Status ...
- bzoj 2243 [SDOI2011]染色(树链剖分,线段树)
2243: [SDOI2011]染色 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 4637 Solved: 1726[Submit][Status ...
- [bzoj4196][Noi2015]软件包管理器_树链剖分_线段树
软件包管理器 bzoj-4196 Noi-2015 题目大意:Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助你从软件 ...
随机推荐
- JAVAEE——BOS物流项目05:OCUpload、POI、pinyin4J、重构分页代码、分区添加、combobox
1 学习计划 1.实现区域导入功能 n OCUpload一键上传插件使用 n 将文件上传到Action n POI简介 n 使用POI解析Excel文件 n 完成数据库操作 n 使用pinyin4J生 ...
- linear-grident的属性和使用
css3新增Gradient属性,用来增加渐变的效果,渐变分为线性渐变 linear-grident 和 径向渐变 radial-grident,这篇文章主要介绍线性渐变linear-grident ...
- ConcurrenHashMap源码分析(二)
本篇博客的目录: 一:put方法源码 二:get方法源码 三:rehash的过程 四:总结 一:put方法的源码 首先,我们来看一下segment内部类中put方法的源码,这个方法它是segment片 ...
- 自定义状态栏的颜色及navigation的title颜色
1.在info.plist中添加View controller-based status bar appearance,值为NO 2.在设置状态栏的地方添加代码 [[UIApplication sha ...
- MySQL中order by排序时,数据存在null咋办
order by排序是最常用的功能,但是排序有时会遇到数据为空null的情况,这样排序就会乱了,这里以MySQL为例,记录我遇到的问题和解决思路. 问题: 网页要实现table的行鼠标拖拽排序,我用A ...
- word在页眉中插入页码
编辑页眉时,插入-页码-当前位置-普通数字
- LNMP安装后MYSQL数据库无法远程访问解决
解决思路: 之前也遇到过这个问题,解决的途径也是五花八门,从百度和Google上也看到各种解决方案,基本上分以下几种: 没有给root对应的权限 -- @'192.168.1.123'可以替换为@'% ...
- Mysql根据指定字段的int值查出在当前列表的排名
先看表结构和数据: DROP TABLE IF EXISTS `ndb_record`; CREATE TABLE `ndb_record` ( `id` bigint(20) NOT NULL AU ...
- SDL 2.0 如何在 windows 上使用?
https://wiki.libsdl.org/APIByCategory http://adolfans.github.io/sdltutorialcn/sdl-2-dot-0-tutorial-i ...
- C#标识符