是不是数据较弱?
查看原帖
是不是数据较弱?
922691
Hisy楼主2024/10/9 20:33

我在随机数据对拍的时候,发现有 RE 的情况。

因为莫队+平衡树中,莫队不断删除并不会重置 cntcnt,所以理论 mm 到顶的极品数据能够将值域较小的 Treap 卡掉。

是不是因为写法问题,栈重置不知道为什么竟然 T 了。请求证明或者调代码。

#include<bits/stdc++.h>
#define MAXN 100001
#define MAXM 50005
using namespace std;
struct node{
	int l,r,k,id,part;
}query[MAXM];
struct Node{
	int lson,rson,val,rnd,size;
}tree[MAXN];
int stk[MAXN];
int n,m,top,root,a[MAXN],ans[MAXN];
inline int newnode(int val){
	tree[stk[top]].val=val;
	tree[stk[top]].size=1;
	tree[stk[top]].rnd=rand();
	return stk[top--];
}
inline void push_up(int root){
	tree[root].size=tree[tree[root].lson].size+tree[tree[root].rson].size+1;
}
inline void split(int root,int val,int &x,int &y){
	if(root==0){
		x=y=0;
		return;
	}
	if(tree[root].val<=val){
		x=root;
		split(tree[root].rson,val,tree[root].rson,y);
	}else{
		y=root;
		split(tree[root].lson,val,x,tree[root].lson);
	}
	push_up(root);
}
inline int merge(int x,int y){
	if(!x||!y){
		return x+y;
	}
	if(tree[x].rnd<tree[y].rnd){
		tree[x].rson=merge(tree[x].rson,y);
		push_up(x);
		return x;
	}
	tree[y].lson=merge(x,tree[y].lson);
	push_up(y);
	return y;
}
inline void add(int val){
	int x,y;
	split(root,val,x,y);
	root=merge(merge(x,newnode(val)),y);
//	cout<<tree[root].size<<endl;
}
inline void del(int val){
	int x,y,z;
	split(root,val,x,z);
	split(x,val-1,x,y);
	stk[++top]=y;
	y=merge(tree[y].lson,tree[y].rson);
	root=merge(merge(x,y),z);
//	cout<<tree[root].size<<endl;
}
int get_val(int root,int rank){
	if(rank<=tree[tree[root].lson].size){
		return get_val(tree[root].lson,rank);
	}
	if(rank==tree[tree[root].lson].size+1){
		return root;
	}
	return get_val(tree[root].rson,rank-tree[tree[root].lson].size-1);
}
inline bool cmp(node x,node y){
	if(x.part!=y.part){
		return x.part<y.part;
	}
	return (x.part&1)?x.r<y.r:x.r>y.r;
}
int main(){
	srand(time(0));
	scanf("%d %d",&n,&m);
	for(int i=1;i<=n;++i){
		scanf("%d",&a[i]);
		stk[++top]=i;
	}
	int newn=sqrt(n);
	for(int i=1;i<=m;++i){
		scanf("%d %d %d",&query[i].l,&query[i].r,&query[i].k);
		query[i].id=i;
		query[i].part=query[i].l/newn;
	}
	sort(query+1,query+1+m,cmp);
	int l=1,r=0;
	for(int i=1;i<=m;++i){
		while(l>query[i].l){
			add(a[--l]);
		}
		while(r<query[i].r){
			add(a[++r]);
		}
		while(l<query[i].l){
			del(a[l++]);
		}
		while(r>query[i].r){
			del(a[r--]);
		}
		ans[query[i].id]=tree[get_val(root,query[i].k)].val;
	}
	for(register int i=1;i<=m;++i){
		printf("%d\n",ans[i]);
	}
	return 0;
}
2024/10/9 20:33
加载中...