社区讨论

树套树这长长的东西有人帮吗=-=

P3380【模板】树套树参与者 5已保存回复 4

讨论操作

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

当前回复
4 条
当前快照
1 份
快照标识符
@mi7x8l3j
此快照首次捕获于
2025/11/21 05:06
4 个月前
此快照最后确认于
2025/11/21 05:06
4 个月前
查看原帖
感觉好难改啊=-= 找到好多错了但样例还是过不去
这么长的东西应该没人会帮吧
CPP
#include <algorithm>
#include <cstring>
#include <cstdio>
#define N 50010
#define INF 0x3fffffff
inline int re() {
	int x = 0; char q = getchar();
	while (q < '0' || q > '9') q = getchar();
	while ('0' <= q && q <= '9') x = x * 10 + q - 48,q = getchar();
	return x;
}
struct splay{int fa,son[2],siz,tie,v;}e[N << 6];
int tr[N << 2],root[N],v[N],tot,lim,n = re(),m = re();
inline int max(int x,int y) {return x > y ? x : y;}
inline int min(int x,int y) {return x < y ? x : y;}
inline void rotate(int x) {
	int y = e[x].fa,z = e[y].fa,mode = e[y].son[0] == x;
	e[z].son[e[z].son[1] == y] = x;
	e[x].fa = z;
	e[y].son[mode ^ 1] = e[x].son[mode];
	e[e[x].son[mode]].fa = y;
	e[x].son[mode] = y;
	e[y].fa = x;
	e[y].siz = e[e[y].son[0]].siz + e[e[y].son[1]].siz + e[y].tie;
	e[x].siz = e[e[x].son[0]].siz + e[e[x].son[1]].siz + e[x].tie;
}
inline void splay(int rt,int x) {
	while (e[x].fa) {
		int y = e[x].fa,z = e[y].fa;
		if (z) {
			if ((e[y].son[0] == x) ^ (e[z].son[0] == y)) rotate(x);
			else rotate(y);
		} rotate(x);
	}
	root[rt] = x;
}
inline int find(int now,int w) {
	while (e[now].v != w)
		if (e[now].v > w) {
			if (e[now].son[0]) now = e[now].son[0];
			else break;
		} else {
			if (e[now].son[1]) now = e[now].son[1];
			else break;
		}
	return now;
}
inline void add(int f,int w) {
	e[++tot].fa = f;
	e[tot].siz = 1;
	e[tot].tie = 1;
	e[tot].v = w;
}
inline void ins(int rt,int p) {
	int pos = find(root[rt],p);
	if (e[pos].v == p) ++e[pos].tie; else
	add(pos,p),e[pos].son[e[pos].v < p] = tot;
	for (int now = pos ; now ; ++e[now].siz,now = e[now].fa);
	splay(rt,e[pos].v == p ? pos : tot);
}
inline void del(int len,int p) {
	int rt = root[len],pos = find(rt,p); splay(len,pos);
	if (e[pos].tie > 1) {--e[pos].tie,--e[pos].siz; return;}
	if (!e[pos].son[0])
		e[e[pos].son[1]].fa = 0,
		root[len] = e[pos].son[1];
	else {
		e[e[pos].son[0]].fa = 0;
		int lax = find(e[pos].son[0],INF);
		splay(len,lax),rt = root[len];
		e[rt].siz += e[e[pos].son[1]].siz;
		e[rt].son[1] = e[pos].son[1];
		e[e[pos].son[1]].fa = rt;
	}
	e[pos].son[0] = 0;
	e[pos].son[1] = 0;
	e[pos].siz = 0;
	e[pos].tie = 0;
	e[pos].fa = 0;
	e[pos].v = 0;
}
inline void ini(int rt,int w) {
	e[++tot].siz = 1;
	e[tot].v = w;
	root[rt] = tot;
}
inline void build(int l,int r,int len) {
	ini(len,v[r]);
	if (l == r) return;
	int mid = (l + r) >> 1;
	build(l,mid,len << 1);
	build(mid + 1,r,len << 1 | 1);
	for (int p = l ; p < r ; ++ p) ins(len,v[p]);
}
inline int rnk(int rt,int p) {
	int pos = find(root[rt],p); splay(rt,pos);
	return e[e[rt].son[0]].siz;
}
inline int rank(int l,int r,int len,int i,int j,int k) {
	if (i <= l && r <= j) return rnk(len,k);
	int mid = (l + r) >> 1,ans = 0;
	if (i <= mid) ans = rank(l,mid,len << 1,i,j,k);
	if (mid < j) ans += rank(mid + 1,r,len << 1 | 1,i,j,k);
	return ans;
}
inline int tkth(int i,int j,int k) {
	int mx = lim;
	for (int rk,mn=0,mi=(mn+mx)>>1;mn!=mx;mi=(mn+mx)>>1)
	rk=rank(1,n,1,i,j,k)+1,rk<k?mn+mi+1:mx=mi;
	return mx;
}
inline void update(int l,int r,int len,int i,int w) {
	del(len,v[i]),ins(root[len],w);
	if (l == r) return;
	int mid = (l + r) >> 1;
	if (i <= mid) update(l,mid,len << 1,i,w);
	else update(mid + 1,r,len << 1 | 1,i,w);
}
inline int pre(int rt,int p) {
	int pos = find(root[rt],p); splay(rt,pos);
	return e[pos].v < p ? e[pos].v : e[find(e[pos].son[0],INF)].v;
}
inline int fpre(int l,int r,int len,int i,int j,int k) {
	if (i <= l && r <= j) return pre(len,k);
	int mid = (l + r) >> 1,ans = 0;
	if (i <= mid) ans = fpre(l,mid,len << 1,i,j,k);
	if (mid < j) ans = max(ans,fpre(mid + 1,r,len << 1 | 1,i,j,k));
	return ans;
}
inline int suc(int rt,int p) {
	int pos = find(root[rt],p); splay(rt,pos);
	return e[pos].v > p ? e[pos].v : e[find(e[pos].son[1],0)].v;
}
inline int fsuc(int l,int r,int len,int i,int j,int k) {
	if (i <= l && r <= j) return suc(len,k);
	int mid = (l + r) >> 1,ans = INF;
	if (i <= mid) ans = fsuc(l,mid,len << 1,i,j,k);
	if (mid < j) ans = min(ans,fsuc(mid + 1,r,len << 1 | 1,i,j,k));
	return ans;
}
int main() {
	for (int a = 1 ; a <= n ; ++ a) lim = max(lim,v[a] = re());
	build(1,n,1);
	for (int mode,i,j,k ; m ; -- m) {
		mode = re(),i = re(),j = re();
		switch (mode) {
			case 1:k = re(),printf("%d\n",rank(1,n,1,i,j,k) + 1);break;
			case 2:k = re(),printf("%d\n",tkth(i,j,k));break;
			case 3:update(1,n,1,i,j),v[i] = j;break;
			case 4:k = re(),printf("%d\n",fpre(1,n,1,i,j,k));break;
			case 5:k = re(),printf("%d\n",fsuc(1,n,1,i,j,k));break;
		}
	}
	return 0;
}

回复

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

正在加载回复...