题目:http://oi.tju.edu.cn/problem/view/1113.html
经典的东西。。求排名。
平衡树。。参照某大牛的模版打了一遍。用的treap实现的。。自己用了离散化+线段树实现了一遍。戳爆了。打了接近一个小时才搞定。
平衡树,treap版
#include <cstdio> #include <cstring> #include <cstdlib> #define inf 1000000000 struct node{ int aux,key,cnt,size; node *left,*right; }; typedef node *Tnode; Tnode root,nilpoint; inline void renew(Tnode &root){ root->size=root->cnt+root->left->size+root->right->size; } inline void LeftRotate(Tnode &root){ Tnode t=root->left; root->left=t->right; t->right=root; renew(root); renew(t); root=t; } inline void RightRotate(Tnode &root){ Tnode t=root->right; root->right=t->left; t->left=root; renew(root); renew(t); root=t; } inline void Insert(Tnode &root,int key){ if (root==nilpoint) { root=new node; root->left=root->right=nilpoint; root->key=key; root->cnt=root->size=1; root->aux=((rand()<<15)+rand())%inf; return; } if (root->key==key) ++root->cnt; else if (key<root->key) { Insert(root->left,key); if (root->left->aux<root->aux) LeftRotate(root); }else if (key>root->key) { Insert(root->right,key); if (root->right->aux<root->aux) RightRotate(root); } renew(root); } inline void Delete(Tnode &root,int key) { if (key==root->key) { if (root->left==nilpoint && root->right==nilpoint) { if (root->cnt>1) --root->cnt,--root->size; else root=nilpoint; return; } if (root->left->aux<root->right->aux) { LeftRotate(root); Delete(root->right,key); }else { RightRotate(root); Delete(root->left,key); } renew(root); return; } if (key<root->key) Delete(root->left,key); else Delete(root->right,key); renew(root); } inline int Query(Tnode &root,int rank) { if (rank>root->size) return -1; if (rank<=root->left->size) return Query(root->left,rank); if (rank<=root->cnt+root->left->size) return root->key; return Query(root->right,rank-root->left->size-root->cnt); } int main() { freopen("arr.in","r",stdin); freopen("arr.out","w",stdout); nilpoint=new node; nilpoint->left=nilpoint->right=nilpoint; nilpoint->cnt=nilpoint->size=0; nilpoint->aux=inf; root=nilpoint; int n,m; scanf("%d%d",&n,&m); for (int i=0;i<m;++i) { char op[10]; int x,y; scanf("%s%d",op,&x); if (op[0]=='i') Insert(root,x); else { y=Query(root,x); printf("%d\n",y); Delete(root,y); } } return 0; }
离散化+线段树
#include <cmath> #include <ctime> #include <iostream> #include <string> #include <vector> #include <cstdio> #include <cstdlib> #include <cstring> #include <queue> #include <map> #include <set> #include <algorithm> #include <cctype> #include <stack> #include <deque> using namespace std; typedef long long LL; #define eps 10e-9 #define inf 0x3f3f3f3f const int maxn = 100000+100; char op[maxn][10]; int a[maxn],c[maxn]; struct node{ int in,v,nv; bool operator < (const node &c) const { return v<c.v; } }b[maxn]; int sum[maxn<<2],flag[maxn<<2],val[maxn<<2]; void build(int id,int l,int r){ if(l==r){ flag[id]=0; sum[id]=0; return ; } int m=(l+r)>>1; build(id<<1,l,m); build(id<<1|1,m+1,r); } void insert(int id,int goal,int l,int r,int op,int v){ if(l==goal&&r==goal){ flag[id]+=op; sum[id]+=op; val[id]=v; return ; } int m=(l+r)>>1; if(m>=goal){ insert(id<<1,goal,l,m,op,v); } else insert(id<<1|1,goal,m+1,r,op,v); sum[id]=sum[id<<1]+sum[id<<1|1]; } int inde; int find(int id,int goal,int l,int r){ int m=(l+r)>>1; if(l==r){ inde=l; return val[id]; } if(sum[id<<1]>=goal){ find(id<<1,goal,l,m); } else { find(id<<1|1,goal-sum[id<<1],m+1,r); } } int main(){ freopen("arr.in","r",stdin); freopen("arr.out","w",stdout); int n,m; scanf("%d %d",&n,&m); int len=0,l=0; for(int i=0;i<m;i++){ scanf("%s %d",op[i],&a[i]); if(op[i][0]=='i'){ b[len].v=a[i]; b[len].in=l++; len++; } } sort(b,b+len); for(int i=0;i<len;i++) c[ b[i].in ]=i+1; build(1,1,m); int cur=0; for(int i=0;i<m;i++){ if(op[i][0]=='i'){ insert(1,c[cur++],1,m,1,a[i]); } else { printf("%d\n",find(1,a[i],1,m)); insert(1,inde,1,m,-1,0); } } return 0; }
作者:w00w12l 发表于2013-1-14 16:17:32 原文链接
阅读:41 评论:0 查看评论