【Codeforces38G】Queue【Splay】【二分】

来源:互联网 发布:焦作淘宝网络公司 编辑:程序博客网 时间:2024/06/11 09:59

题意:

有n个人,第i个人的任务重要度为a[i],良心值为c[i]。
这n个人依次进行排队,当前i-1个人排好队后,第i个人来到队伍末尾,如果站在他前面的人的任务重要度比他的小,第i个人就会说服前面的人与其交换位置,第i人会反复这么做直到他前面的人的任务重要度不小于他,或者他感受到了良心的谴责(即最多交换c[i]次)。你的任务是计算出最后队伍的排列情况。


分析可知,我们需要在后c[i]个数里找到最靠右的大于a[i]的下标。这个可以由Splay维护。

每个节点记录a[i],还有子树中a[i]的最大值。

每次找下标,可以二分下标,然后在Splay中找到这个节点,然后把这个节点Splay到根,返回a[i]的最大值。

再把当前节点插入进去。


#include <cstdio>#include <algorithm>using namespace std;const int maxn = 100005, inf = 0x3f3f3f3f;int n;inline int iread() {int f = 1, x = 0; char ch = getchar();for(; ch < '0' || ch > '9'; ch = getchar()) f = ch == '-' ? -1 : 1;for(; ch >= '0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0';return f * x;}int son[maxn][2], val[maxn], mx[maxn], pre[maxn], size[maxn], id[maxn];int tot1, tot2, sta[maxn], root;inline void newnode(int &x, int c, int f, int p) {x = tot2 ? sta[tot2--] : ++tot1;son[x][0] = son[x][1] = 0;pre[x] = f;size[x] = 1;val[x] = mx[x] = c;id[x] = p;}inline void pushup(int x) {int l = son[x][0], r = son[x][1];size[x] = size[l] + size[r] + 1;mx[x] = max(max(mx[son[x][0]], mx[son[x][1]]), val[x]);}inline void init() {tot1 = tot2 = root = 0;son[0][0] = son[0][1] = val[0] = mx[0] = pre[0] = size[0] = id[0] = 0;newnode(root, inf, root, 0);newnode(son[root][1], 0, root, 0);pushup(son[root][1]); pushup(root);}inline void rotate(int x) {int y = pre[x], z = pre[y], type = son[y][1] == x;pre[son[y][type] = son[x][!type]] = y;pre[x] = z;if(z) son[z][son[z][1] == y] = x;pre[son[x][!type] = y] = x;pushup(y); pushup(x);}inline void splay(int x, int goal) {while(pre[x] != goal) {int y = pre[x], z = pre[y];if(z == goal) rotate(x);else if(son[z][0] == y ^ son[y][0] == x) rotate(x), rotate(x);else rotate(y), rotate(x);}if(goal == 0) root = x;}inline int find(int k) {int x = root;while(k != size[son[x][0]] + 1)if(k <= size[son[x][0]]) x = son[x][0];else k -= size[son[x][0]] + 1, x = son[x][1];return x;}inline int getmax(int x) {int l = find(x);splay(l, 0);return max(mx[son[root][1]], val[root]);}inline void insert(int pos, int c, int idx) {int l = find(pos - 1), r = find(pos);splay(l, 0); splay(r, root);newnode(son[son[root][1]][0], c, son[root][1], idx);pushup(son[root][1]); pushup(root);}void dfs(int x) {if(x == 0) return;dfs(son[x][0]);if(id[x]) printf("%d ", id[x]);dfs(son[x][1]);}int main() {n = iread();init();for(int i = 1; i <= n; i++) {int a = iread(), c = iread();int l = 1, r = i + 1;while(l <= r) {int mid = l + r >> 1;if(getmax(mid) > a) l = mid + 1;else r = mid - 1;}if(i - l + 1 > c) l = i - c + 1;insert(l, a, i);}dfs(root);return 0;}


0 0
原创粉丝点击