[洛谷P2056][ZJOI2007]捉迷藏(2019-7-20考试)
题目大意:有一棵$n(n\leqslant10^6)$个点的树,上面所有点是黑点,有$m$次操作:
- $C\;u$:把点$u$颜色翻转
- $G$:问树上最远的两个黑点的距离,若没有黑点输出$0$
题解:有两个点集,已知它们的直径的端点,可以很快求出点集的并的直径。所有可以用线段树维护所有点的直径。
卡点:考试时没想到
C++ Code:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <queue>
#include <vector>
const int maxn = 1e5 + 10, inf = 0x3f3f3f3f; int head[maxn], cnt;
struct Edge {
int to, nxt;
} e[maxn << 1];
inline void addedge(int a, int b) {
e[++cnt] = (Edge) { b, head[a] }; head[a] = cnt;
e[++cnt] = (Edge) { a, head[b] }; head[b] = cnt;
} int n, m;
int Col[maxn]; int dep[maxn], idx;
int LG[maxn << 1], pos[maxn], st[22][maxn << 1], tot;
inline int _min(int a, int b) { return dep[a] < dep[b] ? a : b; }
inline int _max(int a, int b) { return dep[a] > dep[b] ? a : b; }
void dfs(int u, int fa = 0) {
st[0][++tot] = u, pos[u] = tot;
for (int i = head[u], v; i; i = e[i].nxt) {
v = e[i].to;
if (v != fa) {
dep[v] = dep[u] + 1;
dfs(v, u);
st[0][++tot] = u;
}
}
}
inline int LCA(int x, int y) {
static int l, r, len; l = pos[x], r = pos[y];
if (l > r) std::swap(l, r);
len = LG[r - l + 1];
return _min(st[len][l], st[len][r - (1 << len) + 1]);
}
inline int dis(int x, int y) {
return dep[x] + dep[y] - 2 * dep[LCA(x, y)];
} struct Line {
int l, r;
Line() { }
Line(int _l, int _r) : l(_l), r(_r) { }
inline friend bool operator ! (const Line &rhs) {
return !rhs.l && !rhs.r;
}
inline Line operator + (const Line rhs) const {
if (!*this) return rhs;
if (!rhs) return *this;
const int x = rhs.l, y = rhs.r;
int now = dis(l, r), t; Line ans(l, r);
t = dis(l, x); if (now < t) now = t, ans = Line(l, x);
t = dis(l, y); if (now < t) now = t, ans = Line(l, y);
t = dis(r, x); if (now < t) now = t, ans = Line(r, x);
t = dis(r, y); if (now < t) now = t, ans = Line(r, y);
t = dis(x, y); if (now < t) now = t, ans = Line(x, y);
return ans;
}
} ;
namespace SgT {
Line V[maxn << 2];
void modify(int rt, int l, int r, int p, int v) {
if (l == r) {
V[rt] = Line(v, v);
return ;
}
const int mid = l + r >> 1;
if (p <= mid) modify(rt << 1, l, mid, p, v);
else modify(rt << 1 | 1, mid + 1, r, p, v);
V[rt] = V[rt << 1] + V[rt << 1 | 1];
}
int query() {
return dis(V[1].l, V[1].r);
}
} int num;
int main() {
std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0);
std::cin >> n; num = n;
for (int i = 1, a, b; i < n; ++i) {
std::cin >> a >> b;
addedge(a, b);
}
dfs(1); LG[0] = -1;
for (int i = 1; i <= tot; ++i) LG[i] = LG[i >> 1] + 1;
for (int i = 1; i <= LG[tot]; ++i)
for (int j = 1, len = 1 << i; j + len - 1 <= tot; ++j)
st[i][j] = _min(st[i - 1][j], st[i - 1][j + (len >> 1)]);
for (int i = 1; i <= n; ++i) SgT::modify(1, 1, n, i, i);
std::cin >> m;
while (m --> 0) {
char op;
std::cin >> op;
if (op == 'C') {
static int x;
std::cin >> x;
Col[x] ^= 1;
if (Col[x]) SgT::modify(1, 1, n, x, 0), --num;
else SgT::modify(1, 1, n, x, x), ++num;
} else {
if (!num) std::cout << "-1\n";
else std::cout << SgT::query() << '\n';
}
}
return 0;
}
[洛谷P2056][ZJOI2007]捉迷藏(2019-7-20考试)的更多相关文章
- 洛谷 P2056 [ZJOI2007]捉迷藏 解题报告
P2056 [ZJOI2007]捉迷藏 题目描述 Jiajia和Wind是一对恩爱的夫妻,并且他们有很多孩子.某天,Jiajia.Wind和孩子们决定在家里玩捉迷藏游戏.他们的家很大且构造很奇特,由\ ...
- 洛谷 P2056 [ZJOI2007]捉迷藏 || bzoj 1095: [ZJOI2007]Hide 捉迷藏 || 洛谷 P4115 Qtree4 || SP2666 QTREE4 - Query on a tree IV
意识到一点:在进行点分治时,每一个点都会作为某一级重心出现,且任意一点只作为重心恰好一次.因此原树上任意一个节点都会出现在点分树上,且是恰好一次 https://www.cnblogs.com/zzq ...
- 洛谷 P2056 [ZJOI2007]捉迷藏 题解【点分治】【堆】【图论】
动态点分治入 门 题? 题目描述 Jiajia和Wind是一对恩爱的夫妻,并且他们有很多孩子.某天,Jiajia.Wind和孩子们决定在家里玩捉迷藏游戏.他们的家很大且构造很奇特,由 \(N\) 个屋 ...
- 洛谷 P1169 [ZJOI2007]棋盘制作
2016-05-31 14:56:17 题目链接: 洛谷 P1169 [ZJOI2007]棋盘制作 题目大意: 给定一块矩形,求出满足棋盘式黑白间隔的最大矩形大小和最大正方形大小 解法: 神犇王知昆的 ...
- BZOJ1058或洛谷1110 [ZJOI2007]报表统计
BZOJ原题链接 洛谷原题链接 STL 本题可以直接使用\(\mathtt{STL\ multiset}\)水过去. 因为本题插入数的操作实际上就是将原数列分为\(n\)段,在每一段的末尾插入数,所以 ...
- BZOJ1057或洛谷1169 [ZJOI2007]棋盘制作
BZOJ原题链接 洛谷原题链接 设\(L[i][j],R[i][j],H[i][j]\)表示点\((i,j)\)向左.右.上尽量拓展的左端点.右端点.上端点的坐标. \(L,R\)直接初始化好,\(H ...
- BZOJ1059或洛谷1129 [ZJOI2007]矩阵游戏
BZOJ原题链接 洛谷原题链接 通过手算几组例子后,很容易发现,同一列的\(1\)永远在这一列,且这些\(1\)有且仅有一个能产生贡献,行同理. 所以我们可以只考虑交换列,使得每一行都能匹配一个\(1 ...
- BZOJ1093或洛谷2272 [ZJOI2007]最大半连通子图
BZOJ原题链接 洛谷原题链接 和 Going from u to v or from v to u?(题解)这道题类似,只不过是求最大子图的大小和个数而已. 一样用\(tarjan\)求强连通分量, ...
- 【题解】洛谷P1169 [ZJOI2007] 棋盘制作(坐标DP+悬线法)
次元传送门:洛谷P1169 思路 浙江省选果然不一般 用到一个从来没有听过的算法 悬线法: 所谓悬线法 就是用一条线(长度任意)在矩阵中判断这条线能到达的最左边和最右边及这条线的长度 即可得到这个矩阵 ...
随机推荐
- 洛谷 P3380 【模板】二逼平衡树(树套树)-线段树套splay
P3380 [模板]二逼平衡树(树套树) 题目描述 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 查询k在区间内的排名 查询区间内排名为k的值 修改某一位值上的数 ...
- Cocos CreatorUI系统上
若本号内容有做得不到位的地方(比如:涉及版权或其他问题),请及时联系我们进行整改即可,会在第一时间进行处理. 请点赞!因为你们的赞同/鼓励是我写作的最大动力! 欢迎关注达叔小生的简书! 这是一个有质量 ...
- Java获取两个指定日期之间的所有月份
String y1 = "2016-02";// 开始时间 String y2 = "2019-12";// 结束时间 try { Date startDate ...
- koa post提交数据,koa-bodyparser中间件来获取post提交数据
原生 Nodejs 获取 post 提交数据 首先创建并初始化一个node应用,根路由使用index.ejs模板 var Koa=require('koa') var router = require ...
- java spring学习
目的:为后面学习spring mvc ssm spring boot 打基础. 从单词就能看到有s,记录自学过程,感慨spring 一篇文章都写不完 介绍(来源百度百科): Spring是一个开源框架 ...
- 第10组Alpha冲刺(1/4)
队名:凹凸曼 组长博客 作业博客 组员实践情况 童景霖 过去两天完成了哪些任务 文字/口头描述 学习Android studio和Java,基本了解APP前端的制作 完善项目APP原型 展示GitHu ...
- Unity内存优化之视频讲解
视频为中文讲解,mp4格式,大小3.05GB 目录 扫码时备注或说明中留下邮箱 付款后如未回复请至https://shop135452397.taobao.com/ 联系店主
- Bi-Directional ConvLSTM U-Net with Densley Connected Convolutions
Bi-Directional ConvLSTM U-Net with Densley Connected Convolutions ICCV workshop 2019 2019-09-15 11 ...
- Python numpy 中常用的数据运算
Numpy 精通面向数组编程和思维方式是成为Python科学计算大牛的一大关键步骤.——<利用Python进行数据分析> Numpy(Numerical Python)是Python科学计 ...
- typescript - 5.接口
接口的作用: 在面向对象的编程中,接口是一种规范的定义,它定义了行为和动作的规范,在程序设计里面,接口起到一种限制和规范的作用.接口定义了某一批类所需要遵守的规范,接口不关心这些类的内部状态数据,也不 ...