码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ 1901 Zju 2112 Dynamic Rankings 动态维护第k小 树套树

时间:2014-10-02 13:03:23      阅读:244      评论:0      收藏:0      [点我收藏+]

标签:bzoj   bzoj1903   动态第k小   树套树   treap   

题目大意:动态维护第k小。


思路:线段树套treap,裸题,就是不怎么好写。


CODE:


#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAX 50010
#define INF 1e9
#define LEFT (pos << 1)
#define RIGHT (pos << 1|1)
#define SIZE(x) ((x == NULL) ? 0:x->size)
using namespace std;

struct Complex{
    int val,cnt,size,random;
    Complex *son[2];
    
    Complex() {
        son[0] = son[1] = NULL;
        cnt = size = 1;
        random = rand();
    }
    int Compare(int x) {
        if(x == val)    return -1;
        return x > val;
    }
    void Maintain() {
        size = cnt;
        if(son[0] != NULL)  size += son[0]->size;
        if(son[1] != NULL)  size += son[1]->size;
    }
};

int cnt,asks;
int src[MAX];

char s[10];

Complex *tree[MAX << 2];

void Pretreatment();

void BuildTree(int l,int r,int pos);
int GetRank(int l,int r,int x,int y,int pos,int k);
int GetKth(int x,int y,int k);
void Modify(int l,int r,int aim,int pos,int c);

inline void Rotate(Complex *&a,bool dir);
void Insert(Complex *&a,int x);
void Delete(Complex *&a,int x);
int GetRank(Complex *a,int k);

int main()
{
    Pretreatment();
    cin >> cnt >> asks;
    for(int i = 1;i <= cnt; ++i)
        scanf("%d",&src[i]);
    BuildTree(1,cnt,1);
    for(int i = 1;i <= asks; ++i) {
        scanf("%s",s);
        int x,y,z;
        if(s[0] == 'Q') {
            scanf("%d%d%d",&x,&y,&z);
            printf("%d\n",GetKth(x,y,z));
        }
        if(s[0] == 'C') {
            scanf("%d%d",&x,&y);
            Modify(1,cnt,x,1,y);
            src[x] = y;
        }
    }
    return 0;
}

void Pretreatment()
{
    memset(tree,NULL,sizeof(tree));
}

void BuildTree(int l,int r,int pos)
{
    for(int i = l;i <= r; ++i)
        Insert(tree[pos],src[i]);
    if(l == r)  return ;
    int mid = (l + r) >> 1;
    BuildTree(l,mid,LEFT);
    BuildTree(mid + 1,r,RIGHT);
}

int GetRank(int l,int r,int x,int y,int pos,int k)
{
    if(l == x && y == r)
        return GetRank(tree[pos],k);
    int mid = (l + r) >> 1;
    if(y <= mid) return GetRank(l,mid,x,y,LEFT,k);
    if(x > mid)      return GetRank(mid + 1,r,x,y,RIGHT,k);
    int left = GetRank(l,mid,x,mid,LEFT,k);
    int right = GetRank(mid + 1,r,mid + 1,y,RIGHT,k);
    return left + right;
}

int GetKth(int x,int y,int k)
{
    int L = 0,R = INF;
    while(L <= R) {
        int mid = (L + R) >> 1;
        int temp = GetRank(1,cnt,x,y,1,mid);
        if(temp < k) L = mid + 1;
        else    R = mid - 1;
    }
    return L;
}

void Modify(int l,int r,int aim,int pos,int c)
{
    Delete(tree[pos],src[aim]);
    Insert(tree[pos],c);
    if(l == r)  return ;
    int mid = (l + r) >> 1;
    if(aim <= mid)   Modify(l,mid,aim,LEFT,c);
    else    Modify(mid + 1,r,aim,RIGHT,c);
}

inline void Rotate(Complex *&a,bool dir)
{
    Complex *k = a->son[!dir];
    a->son[!dir] = k->son[dir];
    k->son[dir] = a;
    a->Maintain(),k->Maintain();
    a = k;
}

void Insert(Complex *&a,int x)
{
    if(a == NULL) {
        a = new Complex();
        a->val = x;
        return ;
    }
    int dir = a->Compare(x);
    if(dir == -1)
        a->cnt++;
    else {
        Insert(a->son[dir],x);
        if(a->son[dir]->random > a->random)
            Rotate(a,!dir);
    }
    a->Maintain();
}

void Delete(Complex *&a,int x)
{
    int dir = a->Compare(x);
    if(dir != -1)
        Delete(a->son[dir],x);
    else {
        if(a->cnt > 1)    a->cnt--;
        else {
            if(a->son[0] == NULL)    a = a->son[1];
            else if(a->son[1] == NULL)   a = a->son[0];
            else {
                bool _dir = (a->son[0]->random > a->son[1]->random);
                Rotate(a,_dir);
                Delete(a->son[_dir],x);
            }
        }
    }
    if(a != NULL)   a->Maintain();
}

int GetRank(Complex *a,int k)
{
    if(a == NULL)   return 0;
    if(k < a->val)   return GetRank(a->son[0],k);
    int p = SIZE(a->son[0]) + a->cnt;
    if(k > a->val)  p += GetRank(a->son[1],k);
    return p;
}


BZOJ 1901 Zju 2112 Dynamic Rankings 动态维护第k小 树套树

标签:bzoj   bzoj1903   动态第k小   树套树   treap   

原文地址:http://blog.csdn.net/jiangyuze831/article/details/39735881

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!