您的位置:首页 > 运维架构

Treap 维护集合模板

2017-12-31 14:24 281 查看
该集合不允许出现重复元素,支持插入一个元素,删除一个元素,查询元素x的排名,以及查询排名为x的元素。

Treap.cpp

#include<cstdio>
#include<cstdlib>
#include<algorithm>
using namespace std;
const int maxn=1000000+10;
namespace Treap{
int ch[maxn][2],k[maxn],r[maxn],siz[maxn],ncnt;
int Root=0;void init(){Root=0;ncnt=0;}
int _cmp(int t,int x){
if(k[t]==x)return -1;
return x < k[t] ? 0 : 1;
}
void maintain(int t){
siz[t]=siz[ch[t][0]]+siz[ch[t][1]]+1;
}
void rotate(int& t,int d){
int k=ch[t][d^1];
ch[t][d^1]=ch[k][d];ch[k][d]=t;
maintain(t);t=k;maintain(k);
}
void insert(int& t,int x){
if(t==0){
t=++ncnt;ch[t][0]=ch[t][1]=0;
k[t]=x;r[t]=rand();siz[t]=1;
}else{
int d=_cmp(t,x);if(d==-1)return;
insert(ch[t][d],x);maintain(t);
if(r[t]<r[ch[t][d]])rotate(t,d^1);
}
}
void erase(int& t,int x){
if(t==0)return;     int d=_cmp(t,x);
if(d==-1){
if(ch[t][0]==0 && ch[t][1]==0)t=0;
else if(ch[t][0]==0 || ch[t][1]==0)
t=ch[t][0]+ch[t][1];
else{
rotate(t,0);erase(ch[t][0],x);
maintain(t);
}
}else erase(ch[t][d],x),maintain(t);
}
int rank(int t,int x){
if(t==0)return 1;   int d=_cmp(t,x);
if(d==-1)return siz[ch[t][0]]+1;
int ans=rank(ch[t][d],x);
return d==1 ? ans+siz[ch[t][0]]+1 : ans;
}
int _comp(int x,int y){
if(x==y)return -1;
return x>y ? 0 : 1;
}
int xth(int t,int x){
if(t==0)return x<=0 ? -0x7f7f7f7f : 0x7f7f7f7f;
int d=_comp(siz[ch[t][0]]+1,x);
if(d==-1)return k[t];
if(d== 1)x-=siz[ch[t][0]]+1;
return xth(ch[t][d],x);
}
void insert(int x){     insert(Root,x);}
void erase (int x){      erase(Root,x);}
int  rank  (int x){return rank(Root,x);}
int  xth   (int x){return  xth(Root,x);}
}
#include<cctype>
int geti(){
int ans=0;int flag=0;char c=getchar();
while(!isdigit(c)){flag|=c=='-';c=getchar();}
while( isdigit(c)){ans=ans*10+c-'0';c=getchar();}
return flag?-ans:ans;
}
template<class T>inline void puti(T x){
if(x<0)x=-x,  putchar('-');
if(x>9)puti(x/10); putchar(x%10+'0');
}
int main(){
int q=geti();//instructions
while(q--){
int op=geti(),x=geti();
if(op==1)    Treap::insert(x);//insert
else if(op==2)     Treap::erase(x);//erase
else if(op==3)puti(Treap::rank(x)),putchar('\n');//rank
else if(op==4) puti(Treap::xth(x)),putchar('\n');//xth
}
return 0;
}


bforce.cpp 暴力程序

#include<cstdio>
#include<cstdlib>
#include<algorithm>
using namespace std;
const int maxn=1000000+10;bool exist[maxn];
int rank(int x){
int ans=0;
for(int i=1;i<x;i++)ans+=exist[i];
return ans+1;
}
int xth(int x){
for(int i=1;x;i++){
x-=exist[i];if(x==0)return i;
}
}
int main(){
int q;scanf("%d",&q);
while(q--){
int op,x;scanf("%d%d",&op,&x);
if(op==1)exist[x]=1;
else if(op==2)exist[x]=0;
else if(op==3)printf("%d\n",rank(x));
else if(op==4) printf("%d\n",xth(x));
}
return 0;
}


data.cpp 数据生成器

#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<ctime>
using namespace std;
int rand(int L,int R){return rand()%(R-L+1)+L;}
bool exist[1000000+10];int cnt=0;
int main(){
srand(time(NULL));
int n=rand(50,100);printf("%d\n",n);
while(cnt<30){
int x=rand(1,1000);
if(exist[x])continue;
exist[x]=1;cnt++;
printf("1 %d\n",x);
}
while(cnt>20){//erase
for(int j=1;j<=1000 && cnt>20;j++){
if(exist[j] && (rand()&1)){
cnt--;exist[j]=0;printf("2 %d\n",j);
}
}
}
for(int i=41;i<=n;i++){
int op=rand(3,4);
if(op==3){
int x;
while(1)for(int i=1;i<=1000;i++)
if(exist[i] && (rand()&1)){
x=i;goto outside;
}
outside:printf("3 %d\n",x);
}else if(op==4){
int x=rand(1,cnt);
printf("4 %d\n",x);
}
}
return 0;
}


try.bat 对拍程序

@echo off
set /a i=1
:begin
if %i% GTR 100 goto end
echo round %i% ...
data.exe   > input.txt
treap.exe  < input.txt > output.txt
bforce.exe < input.txt > std.txt
fc output.txt std.txt
if errorlevel 1 pause
set /a i=i+1
goto begin
:end
echo end!
pause
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: