超级数组

来源:互联网 发布:minecraft像素画软件 编辑:程序博客网 时间:2024/04/30 06:24

题目:http://oi.tju.edu.cn/problem/view/1113.html

经典的东西。。求排名。

平衡树。。参照某大牛的模版打了一遍。用的treap实现的。。自己用了离散化+线段树实现了一遍。戳爆了。打了接近一个小时才搞定。


平衡树,treap版

#include <cstdio>#include <cstring>#include <cstdlib>#define inf 1000000000struct 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 0x3f3f3f3fconst 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;}


原创粉丝点击