外话:最近洛谷加了好多好题啊...原题入口 这题好像是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)的更多相关文章

  1. HDU 4366 Successor(树链剖分+zkw线段树+扫描线)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=4366 [题目大意] 有一个公司,每个员工都有一个上司,所有的人呈树状关系,现在给出每个人的忠诚值和 ...

  2. 【BZOJ3531】旅行(树链剖分,线段树)

    [BZOJ3531]旅行(树链剖分,线段树) 题面 Description S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足 从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教 ...

  3. 【BZOJ5507】[GXOI/GZOI2019]旧词(树链剖分,线段树)

    [BZOJ5507][GXOI/GZOI2019]旧词(树链剖分,线段树) 题面 BZOJ 洛谷 题解 如果\(k=1\)就是链并裸题了... 其实\(k>1\)发现还是可以用类似链并的思想,这 ...

  4. 【洛谷5439】【XR-2】永恒(树链剖分,线段树)

    [洛谷5439][XR-2]永恒(树链剖分,线段树) 题面 洛谷 题解 首先两个点的\(LCP\)就是\(Trie\)树上的\(LCA\)的深度. 考虑一对点的贡献,如果这两个点不具有祖先关系,那么这 ...

  5. bzoj 4034 [HAOI2015] T2(树链剖分,线段树)

    4034: [HAOI2015]T2 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 1536  Solved: 508[Submit][Status] ...

  6. bzoj 1036 [ZJOI2008]树的统计Count(树链剖分,线段树)

    1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 10677  Solved: 4313[Submit ...

  7. poj 3237 Tree(树链剖分,线段树)

    Tree Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 7268   Accepted: 1969 Description ...

  8. bzoj 3626 [LNOI2014]LCA(离线处理+树链剖分,线段树)

    3626: [LNOI2014]LCA Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1272  Solved: 451[Submit][Status ...

  9. bzoj 2243 [SDOI2011]染色(树链剖分,线段树)

    2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 4637  Solved: 1726[Submit][Status ...

  10. [bzoj4196][Noi2015]软件包管理器_树链剖分_线段树

    软件包管理器 bzoj-4196 Noi-2015 题目大意:Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助你从软件 ...

随机推荐

  1. Orleans之EventSourcing

    Orleans之EventSourcing 这是Orleans系列文章中的一篇.首篇文章在此 引入: 如果没有意外,我再这篇文章中用ES代替EventSourcing,如果碰到"事件回溯&q ...

  2. [bzoj3875] [Ahoi2014]骑士游戏

    3875: [Ahoi2014]骑士游戏 Time Limit: 30 Sec  Memory Limit: 256 MBSubmit: 844  Solved: 440[Submit][Status ...

  3. Mysql(二):库操作

    一 系统数据库 information_schema: 虚拟库,不占用磁盘空间,存储的是数据库启动后的一些参数,如用户表信息.列信息.权限信息.字符信息等performance_schema: MyS ...

  4. 我不知道的行高——line-height

    概述 对于块级元素,CSS属性line-height指定了元素内部line-boxes的最小高度. 对于非替代行内元素,line-height用于计算line box的高度. 对于替代行内元素,如bu ...

  5. 17_8_9 Spring 注入

    1 Spring 的 Bean 的属性注入: 构造方法的方式注入属性: <!-- 第一种:构造方法的方式 --> <bean id="car" class=&qu ...

  6. 在Ubuntu上安装PHPStudy组件

    phpStudy for Linux (lnmp+lamp一键安装包) phpStudy Linux版&Win版同步上线 支持Apache/Nginx/Tengine/Lighttpd/IIS ...

  7. ubuntu上lamp环境搭建

    首先,介绍个彻底删除linux已经安装的软件的方法. sudo apt-get purge mysql-server mysql-client mysql-common mysql-server-5. ...

  8. python+flask:实现POST接口功能

    1.首先需要安装python和flask,这个是必须的嘛. 2.我们这里实现的是一个POST功能的简单接口. from flask import Flask, request, jsonify imp ...

  9. nyoj 1129 Salvation 模拟

    思路:每个坐标有四种状态,每个点对应的每种状态只能走一个方向,如果走到一个重复的状态说明根本不能走到终点,否则继续走即可. 坑点:有可能初始坐标四周都是墙壁,如果不判断下可能会陷入是死循环. 贴上测试 ...

  10. HDU - 1907 John 反Nimm博弈

    思路: 注意与Nimm博弈的区别,谁拿完谁输! 先手必胜的条件: 1.  每一个小游戏都只剩一个石子了,且SG = 0. 2. 至少有一堆石子数大于1,且SG不等于0 证明:1. 你和对手都只有一种选 ...