记录编号 324073 评测结果 AAAAAAAAAA
题目名称 动态排名系统 最终得分 100
用户昵称 Gravatarsxysxy 是否通过 通过
代码语言 C++ 运行时间 4.430 s
提交时间 2016-10-17 19:13:16 内存使用 4.51 MiB
显示代码纯文本
#include <cstdio>
#include <cstdlib>
#include <cstdarg>
#include <cstring>
#include <cctype>
#include <cmath>
#include <algorithm>
#include <list>
#include <queue>
#include <list>
using namespace std;
int fast_read()
{
    int r;
    char c;
    while(c = getchar())    
    {
        if(c >= '0' && c <= '9')
        {
            r = c^0x30;
            break;
        }
    }
    while(isdigit(c = getchar()))
        r = (r<<3)+(r<<1)+(c^0x30);
    return r;
}

//AVL平衡树
typedef struct _AVL
{
    struct _AVL *left, *right;
    int data;
    int height;
    int size;
}AVLNode, *pNode, *AVLTree;
#define HEIGHT(x) ((x)?(x)->height:-1)
#define SIZE(x) ((x)?(x)->size:0)
void momomo(pNode k)
{
    if(k)
    {
        k -> height = max(HEIGHT(k -> left), HEIGHT(k -> right)) + 1;
        k -> size = SIZE(k -> left) + SIZE(k -> right) + 1;
    }
} 
pNode singleRotateLL(pNode k)
{
    pNode k1 = k -> left;
    k -> left = k1 -> right;
    k1 -> right = k;
    momomo(k);
    momomo(k1);
    return k1;
}
pNode singleRotateRR(pNode k)
{
    pNode k1 = k -> right;
    k -> right = k1 -> left;
    k1 -> left = k;
    momomo(k);
    momomo(k1);
    return k1;
}
pNode doubleRotateLR(pNode k)
{
    k -> left = singleRotateRR(k -> left);
    return singleRotateLL(k);
}
pNode doubleRotateRL(pNode k)
{
    k -> right = singleRotateLL(k -> right);
    return singleRotateRR(k);
}
AVLTree insert(AVLTree t, int x)
{
    if(!t)
    {
        t = new AVLNode;
        t -> data = x;
        t -> size = 1;
        t -> left = t -> right = 0;
    }else
    {
        if(x < t -> data)   
        {
            t -> left = insert(t -> left, x);
            if(HEIGHT(t -> left) - HEIGHT(t -> right) == 2)
            {
                if(x < t -> left -> data)
                    t = singleRotateLL(t); 
                else    
                    t = doubleRotateLR(t);    
            }
        }else 
        {
            t -> right = insert(t -> right, x);
            if(HEIGHT(t -> right) - HEIGHT(t -> left) == 2)
            {
                if(x >= t -> right -> data)
                    t = singleRotateRR(t);
                else
                    t = doubleRotateRL(t);
            }
        }
    }
    momomo(t);
    return t;
}
pNode delBalance(pNode k)
{
    if(HEIGHT(k -> right) - HEIGHT(k -> left) == 2)
    {
        if(k -> right)
        {
            if(HEIGHT(k -> right -> right) >= HEIGHT(k -> right -> left))
                k = singleRotateRR(k);
            else
                k = doubleRotateRL(k);
        }
    }
    if(HEIGHT(k -> left) - HEIGHT(k -> right) == 2)
    {
        if(k -> left)
        {
            if(HEIGHT(k -> left -> left) >= HEIGHT(k -> left -> right))
                k = singleRotateLL(k);
            else
                k = doubleRotateLR(k);
        }
    }
    momomo(k);
    return k;
}
AVLTree delNode(AVLTree t, int x)
{
    if(!t)
        return NULL;
    if(x == t -> data)
    {
        if(!t -> right)
        {
            pNode tmp = t;
            t = t -> left;
            free(tmp);
        }else
        {
            pNode tmp = t -> right;
            while(tmp -> left)
                tmp = tmp -> left;
            t -> data = tmp -> data;
            t -> right = delNode(t -> right, t -> data);
        }
        momomo(t);
        return t;
    }
    if(x < t -> data)
    {
        t -> left = delNode(t -> left, x);
    }else
    {
        t -> right = delNode(t -> right, x);
    }
    if(t -> left)
        t -> left = delBalance(t -> left);
    if(t -> right)
        t -> right = delBalance(t -> right);
    if(t)
        t = delBalance(t);
    return t;
}
//<= x 的个数
int Smaller(pNode t, int x)
{
    if(!t)return 0;
    if(x < t -> data)
        return Smaller(t -> left, x);
    else
        return 1 + SIZE(t -> left) + Smaller(t -> right, x);
}


#define MAXN 100002
int last = 0;
struct _SegNode
{
    int ls, rs;   //左右孩子
    AVLTree rt;   //这个节点的平衡树
    int l, r;  
}ns[MAXN<<1];
int data[MAXN];
int build(int l, int r)
{
    int cur = ++last;
    memset(ns+cur, 0, sizeof(_SegNode));
    ns[cur].l = l;
    ns[cur].r = r;
    ns[cur].rt = NULL;

    for(int i = l; i <= r; i++) //将区间l,r内的数全部插入平衡树
        ns[cur].rt = insert(ns[cur].rt, data[i]);
    if(l == r)
        return cur;
    int mid = (l+r)>>1;
    if(l <= mid)
    {
        ns[cur].ls = build(l, mid);
        ns[cur].rs = build(mid+1, r);
    }
    return cur;
}
//查询区间l, r内 <= n的数的个数
//第一个参数c是线段树节点的下标
int queryTree(int c, int l, int r, int n)
{
    if(ns[c].l == l && ns[c].r == r)
        return Smaller(ns[c].rt, n);  // <= n的数的个数
    int ls= ns[c].ls;
    int rs = ns[c].rs;
    if(r <= ns[ls].r)   //l,r完全在左边
        return queryTree(ls, l, r, n);
    else if(l >= ns[rs].l) //右边
        return queryTree(rs, l, r, n);
    else  //跨越中点,两段之和
        return queryTree(ls, l, ns[ls].r, n) + queryTree(rs, ns[rs].l, r, n);
}
//修改第pos个数为v
void update(int c, int pos, int v)
{ 
    ns[c].rt = delNode(ns[c].rt, data[pos]);   //删掉原来的数
    ns[c].rt = insert(ns[c].rt, v);            //插入新的数
    int ls = ns[c].ls;
    int rs = ns[c].rs;
    if(ls && pos >= ns[ls].l && pos <= ns[ls].r)  //更新左右子树
        update(ls, pos, v);
    else if(rs && pos >= ns[rs].l && pos <= ns[rs].r)
        update(rs, pos, v);
}
void change(int pos, int v)
{
    update(1, pos, v);
    data[pos] = v;     //记录最后一次data[pos]的值
}
int solve(int l, int r, int k)
{
    int x = 0;
    int y = 0x7fffffff;   //二分答案
    int ans = 0;
    while(x <= y)
    {
        int mid = (x+y)>>1;
        int f = queryTree(1, l, r, mid); // l,r内 <= mid的数的个数
        if(f >= k)    
        {
            y = mid-1;
            ans = mid;
        }
        else
            x = mid+1;
    }
    return ans;
}
int main()
{
    freopen("dynrank.in", "r", stdin);
    freopen("dynrank.out", "w", stdout);
    int d = fast_read();
    while(d--)
    {
        int n, m;
        n = fast_read();
        m = fast_read();
        for(int i = 1; i <= n; i++)
            data[i] = fast_read(); 
        last = 0;
        build(1, n);
        while(m--)
        {
            char c;
            while(c = getchar())
            if(c == 'Q' || c == 'C')break;
            if(c == 'Q')
            {
                int a, b, c;
                a = fast_read();
                b = fast_read();
                c = fast_read();
                printf("%d\n", solve(a, b, c));
            }else if(c == 'C')
            {
                int a, b;
                a = fast_read();
                b = fast_read();
                change(a, b);
            }
        }
    }
    return 0;
}