28pts求调(玄关)
查看原帖
28pts求调(玄关)
970132
Hero_Broom楼主2024/8/9 09:11

Record: https://www.luogu.com.cn/record/171507329

Code:

#include<bits/stdc++.h>
using namespace std;
struct node{
	node *l,*r;
	int val,fix,weight;
	int size,lsize,rsize;
};
void Update_Size(node*& root){
	if(root==NULL) return;
	int ans=1;
	Update_Size(root->l);
	if(root->l!=NULL) ans+=root->l->size;
	Update_Size(root->r);
	if(root->r!=NULL) ans+=root->r->size;
	root->size=ans;
}
node* Find_Node(node*& root,int v){
	if(root==NULL) return NULL;
	if(root->val==v) return root;
	else if(v<root->val) return Find_Node(root->l,v);
	else return Find_Node(root->r,v);
}
void Left_Rotate(node* root){
	node* tmp=root->r;
	root->r=tmp->l;
	tmp->l=root;
	root=tmp;
	Update_Size(root);
}
void Right_Rotate(node* root){
	node* tmp=root->l;
	root->l=tmp->r;
	tmp->r=root;
	root=tmp;
	Update_Size(root);
}
void Treap_Insert(node*& root,int v){
	if(Find_Node(root,v)!=NULL){
		Find_Node(root,v)->weight++;
		Update_Size(root);
		return;
	}
	if(root==NULL){
		root=new node();
		root->l=NULL,root->r=NULL;
		root->val=v;
		root->weight=1;
		srand(time(0));
		root->fix=rand();
		Update_Size(root);
		return;
	}
	if(v<root->val){
		Treap_Insert(root->l,v);
		if(root->l->fix<root->fix) Right_Rotate(root);
	}
	else if(v>root->val){
		Treap_Insert(root->r,v);
		if(root->r->fix<root->fix) Left_Rotate(root);
	}
	Update_Size(root);
}
void Treap_Delete(node*& root,int v){
	if(Find_Node(root,v)->weight>0){
		Find_Node(root,v)->weight--;
		Update_Size(root);
		return;
	}
	if(root->val!=v){
		if(v<root->val) Treap_Delete(root->l,v);
		else Treap_Delete(root->r,v);
		return;
	}
	node* tmp=root;
	if(root->l==NULL&&root->r==NULL){
		delete root;
		return;
	}
	if(root->l==NULL&&root->r!=NULL) tmp->l=root->r->l,tmp->r=root->r->r,root=tmp;
	if(root->l!=NULL&&root->r==NULL) tmp->l=root->l->l,tmp->r=root->l->r,root=tmp;
	if(root->l!=NULL&&root->r!=NULL){
		if(root->l->fix<root->r->fix){
			Right_Rotate(root);
			Treap_Delete(root->r,v);
		}else{
			Left_Rotate(root);
			Treap_Delete(root->l,v);
		}
	}
	Update_Size(root);
}
node* Find_Prev(node* root,int v){
	node* tmp=new node();
	node* now=root;
	tmp=NULL;
	while(now!=NULL){
		if(now->val<=v){
			tmp=now;
			now=now->r;
		}else now=now->l;
	}
	return tmp;
}
node* Find_Next(node* root,int v){
	node* tmp=new node();
	node* now=root;
	tmp=NULL;
	while(now!=NULL){
		if(now->val>=v){
			tmp=now;
			now=now->l;
		}else now=now->r;
	}
	return tmp;
}
int Get_The_Kth_Node(node*& root,int k){
	int tmp=root->l==NULL?0:root->l->size;
	if(k<=tmp) return (root->l==NULL?1:Get_The_Kth_Node(root->l,k));
	else if(k<=tmp+root->weight) return root->val;
	else return (root->r==NULL?1:Get_The_Kth_Node(root->r,k-(tmp+root->weight)));
	return -1;
}
int Get_Rank(node*& root,int v){
	int tmp=root->l==NULL?0:root->l->size;
	if(v==root->val) return tmp+1;
	else if(v<root->val) return (root->l==NULL?1:Get_Rank(root->l,v));
	else return (root->r==NULL?root->size+1:tmp+root->weight+Get_Rank(root->r,v));
}
int n,cmd,t;
node* root;
int main(){
	scanf("%d",&n);
	while(n--){
		scanf("%d%d",&cmd,&t);
		if(cmd==1) Treap_Insert(root,t);
		if(cmd==2) Treap_Delete(root,t);
		if(cmd==3) printf("%d\n",Get_Rank(root,t));
		if(cmd==4) printf("%d\n",Get_The_Kth_Node(root,t));
		if(cmd==5) printf("%d\n",Find_Prev(root,t)->val);
		if(cmd==6) printf("%d\n",Find_Next(root,t)->val);
	}
}

貌似是 Get_Rank 函数有问题。

2024/8/9 09:11
加载中...