社区讨论

萌新求助!莫名 RE!

P3302[SDOI2013] 森林参与者 3已保存回复 2

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
2 条
当前快照
1 份
快照标识符
@lo9la1vk
此快照首次捕获于
2023/10/28 13:15
2 年前
此快照最后确认于
2023/10/28 13:15
2 年前
查看原帖
rt,#2 #3 #6 RE 求助!
CPP
#include <bits/stdc++.h>

using namespace std;

namespace IO{
	inline int read(){
		int x = 0;
		char ch = getchar();
		while(!isdigit(ch)) ch = getchar();
		while(isdigit(ch)) x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
		return x;
	}

	template <typename T> inline void write(T x){
		if(x > 9) write(x / 10);
		putchar(x % 10 + '0');
	}
}
using namespace IO;

const int N = 1e5 + 10;
int T, n, m, q, tot, lst;
int a[N], b[N], f[N];
vector <int> g[N << 2];

namespace Segment_Tree{
	int ls[N << 7], rs[N << 7], sum[N << 7];
	int rt[N], cnt;

	inline int build(int l, int r){
		int p = ++cnt;
		if(l == r) return p;
		int mid = (l + r) >> 1;
		ls[p] = build(l, mid);
		rs[p] = build(mid + 1, r);
		return p;
	}

	inline int update(int pre, int l, int r, int val){
		int p = ++cnt;
		ls[p] = ls[pre], rs[p] = rs[pre], sum[p] = sum[pre] + 1;
		if(l == r) return p;
		int mid = (l + r) >> 1;
		if(val <= mid) ls[p] = update(ls[pre], l, mid, val);
		else rs[p] = update(rs[pre], mid + 1, r, val);
		return p;
	}

	inline int query(int x, int y, int p, int fap, int l, int r, int k){
		if(l == r) return b[l];
		int res = sum[ls[x]] + sum[ls[y]] - sum[ls[p]] - sum[ls[fap]];
		int mid = (l + r) >> 1;
		if(k <= res) return query(ls[x], ls[y], ls[p], ls[fap], l, mid, k);
		else return query(rs[x], rs[y], rs[p], rs[fap], mid + 1, r, k - res);;
	}
}
using namespace Segment_Tree;

int fa[N][35], dep[N], siz[N], lg[N];
bool vis[N];

inline void dfs(int x, int p, int root){
	rt[x] = update(rt[p], 1, tot, a[x]);
	vis[x] = 1, f[x] = root;
	fa[x][0] = p, dep[x] = dep[p] + 1, siz[root]++;
	for(int i = 1; i <= 18; ++i) fa[x][i] = fa[fa[x][i - 1]][i - 1];
	for(auto y : g[x])
		if(y != p) dfs(y, x, root);
}

inline int LCA(int x, int y){
	if(dep[x] < dep[y]) swap(x, y);
	while(dep[x] > dep[y])
		x = fa[x][lg[dep[x] - dep[y]]];
	// for(int i = lg[dep[x]]; i >= 0; --i)
	// 	if(dep[fa[x][i]] >= dep[y]) x = fa[x][i];
	if(x == y) return x;
	for(int i = lg[dep[x]]; i >= 0; --i)
		if(fa[x][i] != fa[y][i])
			x = fa[x][i], y = fa[y][i];
	return fa[x][0];
}

int main(){
	// freopen("P3302.in", "r", stdin);
	// freopen("P3302.out", "w", stdout);
	T = read(), n = read(), m = read(), q = read();
	for(int i = 1; i <= n; ++i) b[i] = a[i] = read(), f[i] = i;
	lg[0] = -1;
	for(int i = 1; i <= n; ++i) lg[i] = lg[i >> 1] + 1;
	sort(b + 1, b + 1 + n);
	tot = unique(b + 1, b + 1 + n) - b - 1;
	for(int i = 1; i <= n; ++i) a[i] = lower_bound(b + 1, b + 1 + tot, a[i]) - b;
	for(int i = 1; i <= m; ++i){
		int u = read(), v = read();
		g[u].push_back(v), g[v].push_back(u);
	}
	rt[0] = build(1, tot);
	for(int i = 1; i <= n; ++i)
		if(!vis[i]) dfs(i, 0, i);
	char op[3];
	while(q--){
		scanf("%s", op);
 		int x = read() ^ lst, y = read() ^ lst;
		if(op[0] == 'Q'){
			int k = read() ^ lst;
			int p = LCA(x, y), fap = fa[p][0];
			write(lst = query(rt[x], rt[y], rt[p], rt[fap], 1, tot, k)), puts("");
		}else{
			g[x].push_back(y), g[y].push_back(x);
			int fx = f[x], fy = f[y];
			if(siz[fx] < siz[fy]) dfs(y, x, fx);
			else dfs(x, y, fy);
		}
	}
	return 0;
}

回复

2 条回复,欢迎继续交流。

正在加载回复...