标签:
题目链接: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