mxqz可持久化线段树50pts
  • 板块P4197 Peaks
  • 楼主喵仔牛奶
  • 当前回复0
  • 已保存回复0
  • 发布时间2022/11/12 20:13
  • 上次更新2023/10/27 03:12:06
查看原帖
mxqz可持久化线段树50pts
560516
喵仔牛奶楼主2022/11/12 20:13

https://www.luogu.com.cn/record/93795365

#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 5;
struct edge {
	int to, next;
} e[N];
struct QAQ {
	int u, v, w;
	bool operator < (const QAQ& x) const {
		return w < x.w;
	}
} qwq[N];
int n, m, q, len, u, w, k, edge_cnt, cnt, tot, tim, a[N], h[N], val[N];
int fa[N], t[N], f[N][30], T[N << 5], Ls[N << 5], Rs[N << 5], sum[N << 5], in[N], out[N], head[N];
bool vis[N];
int find(int x) {
	return fa[x] == x ? x : fa[x] = find(fa[x]);
}
void dfs(int u) {
//	cout << "qwq " << u << ' ' << f[u][0] << '\n';
	in[u] = ++ tim, a[tim] = h[u];
	for (int i = head[u]; i; i = e[i].next)
		f[e[i].to][0] = u, dfs(e[i].to);
	out[u] = tim;
}
void add(int u, int v) {
	e[++ edge_cnt].to = v;
	e[edge_cnt].next = head[u];
	head[u] = edge_cnt;
}
void Kruskal() {
	sort(qwq + 1, qwq + 1 + m), tot = n;
	for (int i = 1; i <= n << 1; i ++) fa[i] = i;
	for (int i = 1; i <= m; i ++) {
		int u = find(qwq[i].u), v = find(qwq[i].v);
		if (u == v) continue;
		fa[u] = fa[v] = ++ tot, val[tot] = qwq[i].w;
		add(tot, u), add(tot, v);
//		cout << tot << ' ' << u << '\n';
//		cout << tot << ' ' << v << '\n';
		if (tot == 2 * n + 1) break;
	}
}
int build(int l, int r) {
	int p = ++ cnt, mid = (l + r) >> 1;
	if (l < r) Ls[p] = build(l, mid), Rs[p] = build(mid + 1, r);
	return p;
}
int Kth(int l, int r, int nl, int nr, int k) {
	if (l == r) return l;
	int v = sum[Ls[nr]] - sum[Ls[nl]], mid = (l + r) >> 1;
	if (v >= k) return Kth(l, mid, Ls[nl], Ls[nr], k);
	else return Kth(mid + 1, r, Rs[nl], Rs[nr], k - v);
}
int modify(int p, int l, int r, int k) {
	int rt = ++ cnt;
	Ls[rt] = Ls[p], Rs[rt] = Rs[p], sum[rt] = sum[p] + bool(t[k]);
	if (l < r) {
		int mid = (l + r) >> 1;
		if (mid >= k) Ls[rt] = modify(Ls[rt], l, mid, k);
		else Rs[rt] = modify(Rs[rt], mid + 1, r, k);
	}
	return rt;
}
int query(int u, int w, int k) {
	for (int j = 30; j >= 0; j --)
		if (f[u][j] && val[f[u][j]] <= w)
			u = f[u][j];
//	cout << "Gqwq " << u << ' ' << in[u] << ' ' << out[u] << ' ' << f[u][0] << ' ' << val[f[u][0]] << '\n';
//	for (int i = in[u]; i <= out[u]; i ++)
//		cout << t[a[i]] << ' ';
//	cout << '\n';
	int v = sum[T[out[u]]] - sum[T[in[u] - 1]];
//	cout << v << ' ' << v - k + 1 << '\n';
	if (v < k) return -1;
	return t[Kth(1, len, T[in[u] - 1], T[out[u]], v - k + 1)];
}
int main() {
	cin >> n >> m >> q;
	for (int i = 1; i <= n; i ++)
		cin >> h[i];
	for (int i = 1; i <= m; i ++)
		cin >> qwq[i].u >> qwq[i].v >> qwq[i].w;
	Kruskal();
	for (int i = 1; i <= tot; i ++) if (fa[i] == i) dfs(i);
//	for (int i = 1; i <= tot; i ++)
//		cout << f[i][0] << ' ';
//	cout << '\n';
	for (int j = 1; j <= 30; j ++)
		for (int i = 1; i + (1 << j) <= tot; i ++)
			f[i][j] = f[f[i][j - 1]][j - 1];
	for (int i = 1; i <= tot; i ++) t[i] = a[i];
	sort(t + 1, t + 1 + tot), len = unique(t + 1, t + 1 + tot) - t - 1;
	for (int i = 1; i <= tot; i ++) a[i] = lower_bound(t + 1, t + 1 + len, a[i]) - t;
	T[0] = build(1, len);
	for (int i = 1; i <= tot; i ++)
		T[i] = modify(T[i - 1], 1, len, a[i]);
//	for (int i = 1; i <= tot; i ++)
//		cout << val[i] << ' ';
//	cout << '\n';
//	for (int i = 1; i <= tot; i ++)
//		cout << a[i] << ' ';
//	cout << '\n';
	for (int i = 1; i <= q; i ++) {
		cin >> u >> w >> k;
		cout << query(u, w, k) << '\n';
	}	
	return 0;
}

2022/11/12 20:13
加载中...