【Codeforces#38G】Queue【Splay】【二分】
2016-02-20 22:02
543 查看
题意:
有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]的最大值。
再把当前节点插入进去。
有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; }
相关文章推荐
- [iOS]UIView中的坐标转换
- fixed fluid layout
- iOS-获取UIView的全部层级结构
- UI整理-----part4--UIScrollView
- EasyUI系列学习(十)-Tabs(选项卡)
- 设置UITbaBar和UIBarButtonItem的图片有蓝色图层覆盖
- 百度ueditor学习使用
- LeetCode-334. Increasing Triplet Subsequence
- UINavi中push控制器的时候隐藏TabBar
- leetcode(304) Range Sum Query 2D - Immutable
- 使用 Bluemix™ Live Sync 快速更新 Bluemix 上运行的应用程序实例
- Arduino代码机制-IO
- android小问题--------------------SQLiteDatabase.insert(table, nullColumnHack, values)参数
- scrapy 爬网站 显示 Filtered offsite request to 错误.
- 交换Button中图片与文字的左右位置
- UILabel在Autolayout中的多行显示/动态高度
- 循环中 break 与 continue 的区别
- 分享一款很好的视频处理软件 会声会影X8(huishenghuiyingx8-trial_x64)
- UITableView
- CodeForces 622A Infinite Sequence