「SDOI2013」森林
「SDOI2013」森林
传送门
树上主席树 + 启发式合并
锻炼码力,没什么好说的。
细节见代码。
参考代码:
#include <algorithm>
#include <cstdio>
#define rg register
#define file(x) freopen(x".in", "r", stdin), freopen(x".out", "w", stdout)
using std ::sort; using std ::swap; using std ::unique; using std ::lower_bound;
inline char _getchar() {
static char buf[100000], *p1 = buf, *p2 = buf;
return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1++;
}
template < class T > inline void read(T& s) {
s = 0; rg int f = 0; rg char c = _getchar();
while ('0' > c || c > '9') f |= c == '-', c = _getchar();
while ('0' <= c && c <= '9') s = s * 10 + c - 48, c = _getchar();
s = f ? -s : s;
}
const int _ = 8e4 + 5;
int tot, head[_]; struct Edge { int ver, nxt; } edge[_ << 1];
inline void Add_edge(int u, int v)
{ edge[++tot] = (Edge) { v, head[u] }, head[u] = tot; }
int n, m, q, vis[_], a[_], X0, X[_], top[_], Siz[_], fa[18][_], dep[_];
int tt, rt[_]; struct node { int lc, rc, cnt; } t[_ * 266];
inline void build(int& p, int l = 1, int r = X0) {
p = ++tt, t[p].cnt = 0;
if (l == r) return ;
int mid = (l + r) >> 1;
build(t[p].lc, l, mid), build(t[p].rc, mid + 1, r);
}
inline void update(int& p, int q, int x, int l = 1, int r = X0) {
p = ++tt, t[p] = t[q], ++t[p].cnt;
if (l == r) return ;
rg int mid = (l + r) >> 1;
if (x <= mid) update(t[p].lc, t[q].lc, x, l, mid);
else update(t[p].rc, t[q].rc, x, mid + 1, r);
}
inline int query(int u, int v, int lca, int flca, int k, int l = 1, int r = X0) {
if (l == r) return l;
rg int mid = (l + r) >> 1;
rg int num = t[t[u].lc].cnt + t[t[v].lc].cnt - t[t[lca].lc].cnt - t[t[flca].lc].cnt;
if (num >= k) return query(t[u].lc, t[v].lc, t[lca].lc, t[flca].lc, k, l, mid);
else return query(t[u].rc, t[v].rc, t[lca].rc, t[flca].rc, k - num, mid + 1, r);
}
inline void dfs(int u, int f, int topf, int d) {
vis[u] = 1;
dep[u] = d, fa[0][u] = f, top[u] = topf, ++Siz[topf];
rt[u] = 0, update(rt[u], rt[f], a[u]);
for (rg int i = 1; i <= 16; ++i)
fa[i][u] = fa[i - 1][fa[i - 1][u]];
for (rg int i = head[u]; i; i = edge[i].nxt)
if (edge[i].ver != f) dfs(edge[i].ver, u, topf, d + 1);
}
inline int LCA(int x, int y) {
if (dep[x] < dep[y]) swap(x, y);
for (rg int i = 16; ~i; --i)
if (dep[fa[i][x]] >= dep[y]) x = fa[i][x];
if (x == y) return x;
for (rg int i = 16; ~i; --i)
if (fa[i][x] != fa[i][y]) x = fa[i][x], y = fa[i][y];
return fa[0][x];
}
int main() {
int T; read(T);
read(n), read(m), read(q);
for (rg int i = 1; i <= n; ++i) read(a[i]), X[i] = a[i];
sort(X + 1, X + n + 1);
X0 = unique(X + 1, X + n + 1) - X - 1;
for (rg int i = 1; i <= n; ++i) a[i] = lower_bound(X + 1, X + X0 + 1, a[i]) - X;
build(rt[0]);
for (rg int x, y, o = 1; o <= m; ++o)
read(x), read(y), Add_edge(x, y), Add_edge(y, x);
for (rg int i = 1; i <= n; ++i) if (!vis[i]) dfs(i, 0, i, 1);
for (rg int ans = 0, x, y, k, lca, o = 1; o <= q; ++o) {
rg char C = _getchar();
while (C != 'Q' && C != 'L') C = _getchar();
read(x), x ^= ans;
read(y), y ^= ans;
if (C == 'Q') {
read(k), k ^= ans, lca = LCA(x, y);
ans = X[query(rt[x], rt[y], rt[lca], rt[fa[0][lca]], k)];
printf("%d\n", ans);
} else {
Add_edge(x, y), Add_edge(y, x);
if (Siz[top[x]] < Siz[top[y]]) swap(x, y);
dfs(y, x, top[x], dep[x] + 1);
}
}
return 0;
}
「SDOI2013」森林的更多相关文章
- 「luogu2387」[NOI2014] 魔法森林
「luogu2387」[NOI2014] 魔法森林 题目大意 \(n\) 个点 \(m\) 条边的无向图,每条边上有两个权值 \(a,b\),求从 \(1\) 节点到 \(n\) 节点 \(max\{ ...
- 「ZJOI2016」大森林 解题报告
「ZJOI2016」大森林 神仙题... 很显然线段树搞不了 考虑离线操作 我们只搞一颗树,从位置1一直往后移动,然后维护它的形态试试 显然操作0,1都可以拆成差分的形式,就是加入和删除 因为保证了操 ...
- Loj #3056. 「HNOI2019」多边形
Loj #3056. 「HNOI2019」多边形 小 R 与小 W 在玩游戏. 他们有一个边数为 \(n\) 的凸多边形,其顶点沿逆时针方向标号依次为 \(1,2,3, \ldots , n\).最开 ...
- 「ZJOI2016」解题报告
「ZJOI2016」解题报告 我大浙的省选题真是超级神仙--这套已经算是比较可做的了. 「ZJOI2016」旅行者 神仙分治题. 对于一个矩形,每次我们从最长边切开,最短边不会超过 \(\sqrt{n ...
- 「JLOI2015」管道连接 解题报告
「JLOI2015」管道连接 先按照斯坦纳树求一个 然后合并成斯坦纳森林 直接枚举树的集合再dp一下就好了 Code: #include <cstdio> #include <cct ...
- Loj #3102. 「JSOI2019」神经网络
Loj #3102. 「JSOI2019」神经网络 题目背景 火星探险队发现,火星人的思维方式与人类非常不同,是因为他们拥有与人类很不一样的神经网络结构.为了更好地理解火星人的行为模式,JYY 对小镇 ...
- 「数据结构」Link-Cut Tree(LCT)
#1.0 简述 #1.1 动态树问题 维护一个森林,支持删除某条边,加入某条边,并保证加边.删边之后仍然是森林.我们需要维护这个森林的一些信息. 一般的操作有两点连通性,两点路径权值和等等. #1.2 ...
- Solution -「构造」专练
记录全思路过程和正解分析.全思路过程很 navie,不过很下饭不是嘛.会持续更新的(应该). 「CF1521E」Nastia and a Beautiful Matrix Thought. 要把所有数 ...
- 「译」JUnit 5 系列:条件测试
原文地址:http://blog.codefx.org/libraries/junit-5-conditions/ 原文日期:08, May, 2016 译文首发:Linesh 的博客:「译」JUni ...
随机推荐
- IDEA中使用maven下载插件速度很慢解决方法
1.打开IDEA的File--->settings--->搜索mavaen--->找到settings.xml 2.在settings.xml中添加 <!-- 阿里云仓库 -- ...
- linux查看公网ip的方法
curl ifconfig.me 或者 curl cip.cc
- 我来给你讲清楚Pythony广播
初学python广播搞的人头大,今天老师上课讲了一下,茅塞顿开,zt老师nb 首先说一下后向纬度(这个后向纬度书里边称作低维),举例:(3,4,5)后向纬度是:3*4*5或4*5或5 向量广播的条件有 ...
- 安卓之button按钮
一.需求 短按按钮时显示 您点击了控件:Button 长按按钮时显示 您点击了控件:Button 二.布局xml文件 <?xml version="1.0" encodi ...
- spark实验(三)--Spark和Hadoop的安装(1)
一.实验目的 (1)掌握在 Linux 虚拟机中安装 Hadoop 和 Spark 的方法: (2)熟悉 HDFS 的基本使用方法: (3)掌握使用 Spark 访问本地文件和 HDFS 文件的方法. ...
- MQTT.js browser node 均支持
npm - mqtt 官网手册 https://www.npmjs.com/package/mqtt#weapp 简书用户 使用笔记 https://www.jianshu.com/p/4fd95ca ...
- 洛谷P1164小A点菜(01背包)
题目背景 uim神犇拿到了uoi的ra(镭牌)后,立刻拉着基友小A到了一家……餐馆,很低端的那种. uim指着墙上的价目表(太低级了没有菜单),说:“随便点”. 题目描述 不过uim由于买了一些辅(e ...
- 【PAT甲级】1065 A+B and C (64bit) (20 分)(大数溢出)
题意: 输入三个整数A,B,C(long long范围内),输出是否A+B>C. trick: 测试点2包括溢出的数据,判断一下是否溢出即可. AAAAAccepted code: #defin ...
- 的aspnet_client文件夹
在早期,有一些asp.net组件是默认要调用(从客户端调用)服务器根(域名)下这个子目录里边的文件的. 不过如果你使用高版本的asp.net,那么全都从你的网站里调用了,因为asp.net有了更好地直 ...
- 「CF197B Limit」
题目撞名 题目大意: 给出两个函数 \(P(x),Q(x)\). \(P(x)=a_0 \times x^N+a_1 \times x^{N-1}+a_2 \times x^{N-2} \cdots ...