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

[POJ2761] Feed the dogs (Treap)

时间:2016-07-16 06:43:03      阅读:171      评论:0      收藏:0      [点我收藏+]

标签:

题目链接:http://poj.org/problem?id=2761

题目大意:给你n个数,m次查询,m次查询分别是a,b,k,查询下表从a到b的第k小元素是哪个。这m个区间不会互相包含。

 

Treap,自己学着写了个板子,留贴备用。

离线操作,将区间移动之,删除旧的添加新的。

 

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <map>
#include <set>
#include <string>
#include <bitset>
#include <cmath>
#include <numeric>
#include <iterator>
#include <iostream>
#include <cstdlib>
#include <functional>
#include <queue>
#include <stack>
#include <list>
#include <ctime>
using namespace std;

const int inf = ~0U >> 1;

typedef long long LL;

struct TreapNode {
    int key, val, siz;
    TreapNode* ch[2];
    TreapNode() :val(0), siz(1){ key = rand() - 1; ch[0] = ch[1] = NULL; }
    void rz(){
        siz = 1;
        if (ch[0]) siz += ch[0]->siz;
        if (ch[1]) siz += ch[1]->siz;
    }
    ~TreapNode(){
        if (ch[0]) delete ch[0];
        if (ch[1]) delete ch[1];
    }
};

void rot(TreapNode*& rt, bool d){
    TreapNode* c = rt->ch[d];
    rt->ch[d] = c->ch[!d];
    c->ch[!d] = rt;
    rt->rz(); c->rz();
    rt = c;
}

void Insert(TreapNode*& rt, int val) {
    if (!rt){ rt = new TreapNode(); rt->val = val; return; }
    //if (val == rt->val) return;
    bool d = val > rt->val;
    Insert(rt->ch[d], val);
    if (rt->ch[d]->key < rt->key) rot(rt, d);
    else rt->rz();
}

void Delete(TreapNode*& rt, int val) {
    if (rt == NULL) return;
    if (rt->val == val) {
        if (rt->ch[0] == NULL && rt->ch[1] == NULL) {
            delete rt;
            rt = NULL;
            return;
        }
        else if (rt->ch[0] == NULL) {
            rot(rt, 1);
            Delete(rt->ch[0], val);
        }
        else if (rt->ch[1] == NULL) {
            rot(rt, 0);
            Delete(rt->ch[1], val);
        }
        else {
            bool d = rt->ch[1]->key > rt->ch[0]->key;
            rot(rt, d);
            Delete(rt->ch[!d], val);
        }
    }
    else {
        bool d = val > rt->val;
        Delete(rt->ch[d], val);
    }
    rt->rz();
}

int Select(TreapNode* rt, int k) {
    if (!rt) return -inf;
    if (rt->siz < k) return -inf;
    int r = 0;
    if (!rt->ch[0]) r = 0;
    else r = rt->ch[0]->siz;
    if (r == k - 1) return rt->val;
    if (k - 1 < r) return Select(rt->ch[0], k);
    return Select(rt->ch[1], k - r - 1);
}

int n, m;
int a[100001], ans[50001];
//int ptr = 0;

struct bwl{
    int l, r, k, idx;
    bool operator<(const bwl& b) const{
        return l < b.l;
    }
};

bwl ee[50001];

int main() {
    srand(time(0));
    while (scanf("%d%d", &n, &m) != EOF) {
        TreapNode *root = NULL;
        for (int i = 0; i < n; i++) {
            scanf("%d", &a[i]);
        }
        for (int i = 0; i < m; i++) {
            scanf("%d%d%d", &ee[i].l, &ee[i].r, &ee[i].k);
            ee[i].idx = i;
        }
        sort(ee, ee + m);
        int pre = 1,last = 1;
        for (int i = 0; i < m; i++) {
            if (i == 0) {
                pre = last = ee[i].l;
            }
            while (pre <= last && pre < ee[i].l) {
                Delete(root, a[pre-1]);
                pre++;
            }
            while (last <= n && last <= ee[i].r) {
                Insert(root, a[last-1]);
                last++;
            }
            ans[ee[i].idx] = Select(root, ee[i].k);
        }
        for (int i = 0; i < m; i++) {
            printf("%d\n", ans[i]);
        }
        delete root;
    }
    return 0;
}

/*
 7 2
 1 5 2 6 3 7 4
 1 5 3
 2 7 1
 
 9 3
 1 3 10 2 4 7 7 8 2
 1 3 3
 5 9 2
 3 8 4
 */

 

[POJ2761] Feed the dogs (Treap)

标签:

原文地址:http://www.cnblogs.com/llkpersonal/p/5675113.html

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