社区讨论
这个题是不是卡跳表
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;
}
回复
共 2 条回复,欢迎继续交流。
正在加载回复...