您的位置:首页 > 理论基础 > 数据结构算法

Vijos 1647 treap

2016-09-12 19:00 337 查看
点击打开链接

题意:中文

思路:就是记录哪个用过没用过,然后找第k大,直接用名次树就行了#include <vector>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int inf=0x3f3f3f3f;
const ll INF=0x3f3f3f3f3f3f3f3fll;
const int maxn=100010;
vector<int>G[maxn*10];
int id[maxn],vis[maxn*10];
inline int getint(){
int res=0;
char c=getchar();
bool mi=false;
while(c<'0' || c>'9') mi=(c=='-'),c=getchar();
while('0'<=c && c<='9') res=res*10+c-'0',c=getchar();
return mi ? -res : res;
}
inline ll getll(){
ll res=0;
char c=getchar();
bool mi=false;
while(c<'0' || c>'9') mi=(c=='-'),c=getchar();
while('0'<=c && c<='9') res=res*10+c-'0',c=getchar();
return mi ? -res : res;
}
struct Node{
Node *ch[2];
int r,v,s,weight;
Node(int v):v(v){ch[0]=ch[1]=NULL;r=rand();s=1;weight=1;}
int cmp(int x){
if(x==v) return -1;
return x<v? 0:1;
}
void maintain(){
s=weight;
if(ch[0]!=NULL) s+=ch[0]->s;
if(ch[1]!=NULL) s+=ch[1]->s;
}
};
Node *root;
void Rotate(Node* &o,int d){
Node* k=o->ch[d^1];o->ch[d^1]=k->ch[d];k->ch[d]=o;
o->maintain();k->maintain();o=k;
}
void Insert(Node* &o,int x){
if(o==NULL) o=new Node(x);
else{
if(x==o->v) o->weight++;
else{
int d=x<(o->v)? 0:1;
Insert(o->ch[d],x);
if(o->ch[d]->r>o->r) Rotate(o,d^1);
}
}
o->maintain();
}
void Remove(Node* &o,int x){
int d=o->cmp(x);
if(d==-1){
if(o->weight>1) o->weight--;
else{
Node* u=o;
if(o->ch[0]!=NULL&&o->ch[1]!=NULL){
int d2=(o->ch[0]->r>o->ch[1]->r?1:0);
Rotate(o,d2);Remove(o->ch[d2],x);
}else{
if(o->ch[0]==NULL) o=o->ch[1];
else o=o->ch[0];
delete u;
}
}
}else Remove(o->ch[d],x);
if(o!=NULL) o->maintain();
}
int Kth(Node* o,int k){
// if(o==NULL) return inf;
int s=(o->ch[0]==NULL?0:o->ch[0]->s);
if(k<s+1) return Kth(o->ch[0],k);
else if(k>s+o->weight) return Kth(o->ch[1],k-(s+o->weight));
else return o->v;
}
int get_min(){
if(root==NULL) return -100000000;
Node* now=root;
while(now->ch[0]!=NULL) now=now->ch[0];
return now->v;
}
int main(){
int price,x,y,sum1,sum2,sum3;
memset(vis,0,sizeof(vis));
scanf("%d",&price);
root=NULL;
sum1=sum2=sum3=0;
while(1){
x=getint();
if(x==0) break;
y=getint();
if(x==1){
sum1++;vis[sum1]=1;
G[y].push_back(sum1);
Insert(root,y);
}else if(x==2){
vis[y]=0;
}else{
if(root==NULL||root->s<y) printf("Mei you. Zhe ge ke yi you. Zhe ge zhen mei you!\n");
else{
int tmp=Kth(root,root->s-y+1);
if(tmp>price) printf("Dui bu qi,Mei you.\n");
else{
int flag=0;
for(unsigned int i=0;i<G[tmp].size();i++){
if(vis[G[tmp][i]]){
flag=1;break;
}
}
if(flag) printf("You. %d Yuan.\n",tmp);
else printf("Mei you. Zhe ge ke yi you. Zhe ge zhen mei you!\n");
}
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  数据结构 ACM treap