社区讨论

这个题是不是卡跳表

P6136【模板】普通平衡树(数据加强版)参与者 2已保存回复 2

讨论操作

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

当前回复
2 条
当前快照
1 份
快照标识符
@mhjhy08x
此快照首次捕获于
2025/11/04 02:51
4 个月前
此快照最后确认于
2025/11/04 02:51
4 个月前
查看原帖
如题,,,
CPP
#include <cstdio>
#include <climits>
#include <algorithm>
using namespace std;
template<typename T> T read(){
	T x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
	return x*f;
}
template<typename T> void write(T x){
	if(x<0) putchar('-'),x=-x;
	if(x>9) write(x/10);
	putchar(x%10|'0');
}
const int N=(1e5+10)+(1e6+10),L=21;
int cnt;
int key[N];
int key_count[N];
int level[N];
int next_node[N][L+1];
int len[N][L+1];
void build(){
	cnt=1;
	key[cnt]=INT_MIN;
	level[cnt]=L;
}
int randomLevel(){
	int ans=1;
	while((rand()*1.0/RAND_MAX)<0.5) ans++;
	return min(ans,L);
}
int find(int i,int h,int num){
	while(next_node[i][h]!=0&&key[next_node[i][h]]<num) i=next_node[i][h];
	if(h==1){
		if(next_node[i][h]!=0&&key[next_node[i][h]]==num) return next_node[i][h];
		else return 0;
	}
	return find(i,h-1,num);
}
void addCount(int i,int h,int num){
	while(next_node[i][h]!=0&&key[next_node[i][h]]<num) i=next_node[i][h];
	if(h==1) key_count[next_node[i][h]]++;
	else addCount(i,h-1,num);
	len[i][h]++;
}
int addNode(int i,int h,int j){
	int rightCnt=0;
	while(next_node[i][h]!=0&&key[next_node[i][h]]<key[j]){
		rightCnt+=len[i][h];
		i=next_node[i][h];
	}
	if(h==1){
		next_node[j][h]=next_node[i][h];
		next_node[i][h]=j;
		len[j][h]=key_count[next_node[j][h]];
		len[i][h]=key_count[next_node[i][h]];
		return rightCnt;
	}else{
		int downCnt=addNode(i,h-1,j);
		if(h>level[j]) len[i][h]++;
		else{
			next_node[j][h]=next_node[i][h];
			next_node[i][h]=j;
			len[j][h]=len[i][h]+1-downCnt-key_count[j];
			len[i][h]=downCnt+key_count[j];
		}
		return rightCnt+downCnt;
	}
}

void add(int num){
	if(find(1,L,num)) addCount(1,L,num);
	else{
		key[++cnt]=num;
		key_count[cnt]=1;
		level[cnt]=randomLevel();
		addNode(1,L,cnt);
	}
}
void removeCount(int i,int h,int num){
	while(next_node[i][h]!=0&&key[next_node[i][h]]<num) i=next_node[i][h];
	if(h==1) key_count[next_node[i][h]]--;
	else removeCount(i,h-1,num);
	len[i][h]--;
}
void removeNode(int i,int h,int j){
	if(h<1) return;
	while(next_node[i][h]!=0&&key[next_node[i][h]]<key[j]) i=next_node[i][h];
	if(h>level[j]) len[i][h]--;
	else{
		next_node[i][h]=next_node[j][h];
		len[i][h]+=len[j][h]-1;
	}
	removeNode(i,h-1,j);
}
void remove(int num){
	int j=find(1,L,num);
	if(j!=0){
		if(key_count[j]>1) removeCount(1,L,num);
		else removeNode(1,L,j);
	}
}
int small(int i,int h,int num){
	int rightCnt=0;
	while(next_node[i][h]!=0&&key[next_node[i][h]]<num){
		rightCnt+=len[i][h];
		i=next_node[i][h];
	}
	if(h==1) return rightCnt;
	else return rightCnt+small(i,h-1,num);
}
int getRank(int num){
	return small(1,L,num)+1;
}
int index(int i,int h,int x){
	int c=0;
	while(next_node[i][h]!=0&&c+len[i][h]<x){
		c+=len[i][h];
		i=next_node[i][h];
	}
	if(h==1) return key[next_node[i][h]];
	else return index(i,h-1,x-c);
}
int index(int num){
	return index(1,L,num);
}
int pre(int i,int h,int num){
	while(next_node[i][h]!=0&&key[next_node[i][h]]<num) i=next_node[i][h];
	if(h==1) return i==1?INT_MIN:key[i];
	else return pre(i,h-1,num);
}
int pre(int num){
	return pre(1,L,num);
}
int post(int i,int h,int num){
	while(next_node[i][h]!=0&&key[next_node[i][h]]<num) i=next_node[i][h];
	if(h==1){
		if(next_node[i][h]==0) return INT_MAX;
		if(key[next_node[i][h]]>num) return key[next_node[i][h]];
		i=next_node[i][h];
		if(next_node[i][h]==0) return INT_MAX;
		else return key[next_node[i][h]];
	}else return post(i,h-1,num);
}
int post(int num){
	return post(1,L,num);
}
int main(){
	build();
	int n=read<int>(),m=read<int>();
	for(int i=1,num;i<=n;i++){
		num=read<int>();
		add(num);
	}
	int lastAns=0,ans=0;
	for(int i=1,op,x;i<=m;i++){
		op=read<int>(),x=read<int>();
		x^=lastAns;
		if(op==1) add(x);
		else if(op==2) remove(x);
		else if(op==3) lastAns=getRank(x),ans^=lastAns;
		else if(op==4) lastAns=index(x),ans^=lastAns;
		else if(op==5) lastAns=pre(x),ans^=lastAns;
		else lastAns=post(x),ans^=lastAns;
	}
	printf("%d\n",ans);
	return 0;
} 
样例能过,跳表的板子在P3369也能过,MLE了一大片

回复

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

正在加载回复...