URAL 1439. Battle with You-Know-Who treap树

来源:互联网 发布:全能图片数据恢复 编辑:程序博客网 时间:2024/05/20 07:15

题目来源:URAL 1439. Battle with You-Know-Who

题意:开始有数列1, 2, 3, ... L k输出第k大的数 D k删除第k大的数

思路:treap树插入删除的数 每次二分查找第k大的数为mid 查询treap小于等于mid的数有y个 那么mid应该是第mid-y大的数 与k比较 继续二分

#include <cstdio>#include <cstring>#include <cstdlib>#include <algorithm>using namespace std;const int maxm = 100010;int ch[maxm][2], r[maxm], val[maxm], sum[maxm], num[maxm], cnt, root;void Node(int &rt, int x){    rt = ++cnt;    ch[rt][0] = ch[rt][1] = 0;    r[rt] = rand();    val[rt] = x;    if(cnt > 1)    {sum[rt] = 1;    num[rt] = 1;    }    else    {    sum[rt] = 0;    num[rt] = 0;    }} void maintain(int rt){        sum[rt] = sum[ch[rt][0]]+sum[ch[rt][1]]+num[rt];}void init(){ch[0][0] = ch[0][1] = 0;r[0] = (1LL<<31)-1;val[0] = 0;sum[0] = 0;cnt = 0;root = 0;Node(root, 2000000001);}void rotate(int &rt, int d){    int k = ch[rt][d^1]; ch[rt][d^1] = ch[k][d]; ch[k][d] = rt;    maintain(rt); maintain(k); rt = k;}void insert(int &rt, int x){    if(!rt){        Node(rt, x);        return;    }    else{        if(x == val[rt])            num[rt]++;        else        {            int d = x < val[rt] ? 0 : 1;            insert(ch[rt][d], x);            if(r[ch[rt][d]] < r[rt]) rotate(rt, d^1);        }    }    maintain(rt);}/*void remove(int &rt, int x){    if(val[rt] == x){        val[rt]--;        if(!val[rt]){            if(!ch[rt][0] && !ch[rt][1])            {                rt = 0;                return;            }            else{                int d = r[ch[rt][0]] > r[ch[rt][1]] ? 1 : 0;                rotate(rt, d);                remove(ch[rt][d], x);            }            else{                            }        }    }    else        remove(ch[rt][x>val[rt]], x);    maintain(rt);}*/int kth(int rt, int k){    if(rt == 0)    return 0;if(val[rt] <= k)return sum[ch[rt][0]]+num[rt]+kth(ch[rt][1], k);return kth(ch[rt][0], k);}int main(){int n, m;    while(scanf("%d %d", &n, &m) != EOF)    {        init();        while(m--)        {        char s[10];        int x;        scanf("%s %d", s, &x);        int l = 1, r = n, ans;        //printf("****%d\n", kth(root, 10));    while(l < r)        {        int mid = (l + r) >> 1; int y = kth(root, mid);        if(x > mid-y)        {        l = mid+1;        ans = mid+1;        }        else        {        r = mid;        }//printf("***%d\n", y);        }        if(s[0] == 'L')        {printf("%d\n", l);        }        else        {        //int y = kth(root, x);insert(root, l);        }        }    }    return 0;}


 

0 0
原创粉丝点击