poj-1442 Black Box(Treap)
题目链接:
题意:
给一个序列,m个询问,每个询问是求前x个数中的第i小是多少;
思路:
Treap的入门题目;Treap能实现STL的set实现不了的功能,如名次树(rank tree)rank tree 支持两种新操作,一个是找出第k小元素,一个是找出x的的rank;
AC代码:
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> //#include <bits/stdc++.h> #include <stack> #include <map> using namespace std; #define For(i,j,n) for(int i=j;i<=n;i++) #define mst(ss,b) memset(ss,b,sizeof(ss)); typedef long long LL; template<class T> void read(T&num) { char CH; bool F=false; for(CH=getchar();CH<'0'||CH>'9';F= CH=='-',CH=getchar()); for(num=0;CH>='0'&&CH<='9';num=num*10+CH-'0',CH=getchar()); F && (num=-num); } int stk[70], tp; template<class T> inline void print(T p) { if(!p) { puts("0"); return; } while(p) stk[++ tp] = p%10, p/=10; while(tp) putchar(stk[tp--] + '0'); putchar('\n'); } const LL mod=1e9+7; const double PI=acos(-1.0); const int inf=1e9+10; const int N=1e6+10; const int maxn=1e3+20; const double eps=1e-12; int a[N]; struct Treap { Treap *ch[2]; int siz,key,fix; Treap(int key) { siz=1; fix=rand(); this->key=key; ch[0]=ch[1]=NULL; } int cmp(int x) const { if(x==key)return -1; return x<key? 0:1; } void maintain() { siz=1; if(ch[0]!=NULL)siz+=ch[0]->siz; if(ch[1]!=NULL)siz+=ch[1]->siz; } }; void Rotate(Treap* &o,int d) { Treap* k=o->ch[d^1]; o->ch[d^1]=k->ch[d]; k->ch[d]=o; o->maintain(); k->maintain(); o=k; } void insert(Treap* &o,int x) { if(o==NULL)o=new Treap(x); else { int d=(x<o->key? 0:1); insert(o->ch[d],x); if(o->ch[d]->fix > o->fix)Rotate(o,d^1); } o->maintain(); } int getans(Treap* &o,int x) { //cout<<o->key<<"*****\n"; if(o==NULL||x<=0||x> o->siz)return 0; int s=(o->ch[0] == NULL? 0: o->ch[0]->siz); if(x==s+1)return o->key; else if(x<=s)return getans(o->ch[0],x); else return getans(o->ch[1],x-s-1); } void removetree(Treap* &o) { if(o->ch[0]!=NULL)removetree(o->ch[0]); if(o->ch[1]!=NULL)removetree(o->ch[1]); delete o; o=NULL; } int main() { int n,m; while(scanf("%d%d",&n,&m)!=EOF) { For(i,1,n)read(a[i]); int pre=1,x; Treap* root=NULL; For(i,1,m) { read(x); for(int j=pre;j<=x;j++)insert(root,a[j]); printf("%d\n",getans(root,i)); pre=x+1; } removetree(root); } return 0; }