题目链接:点击打开链接

题意:

给定n个人来排队

每一个人有2个參数。身份优先级和脸皮厚度 ==

来的那个人会排到队尾

假设这个人的优先级比他前面那个人的优先级大就会和前面那个人交换位置。

交换一次脸皮厚度减1, 一直交换到队头或者脸皮厚度为0

交换完毕后下一个人才会到来。

问:

队伍最后的情况(从队头到队尾依次输出每一个人的编号)

思路:splay

维护子树的最小值。

插入时递归插入,若当前点是空就插这个位置。

然后就是裸的splay。。

==

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <queue>
#include <functional>
#include <map>
#include <iostream>
#include <set>
using namespace std;
typedef pair<int,int> pii;
#define ll int
#define inf 1000000
#define N 100005
#define L(x) tree[x].ch[0]
#define R(x) tree[x].ch[1]
#define Size(x) tree[x].siz
#define Val(x) tree[x].val
#define Father(x) tree[x].fa
#define Max(x) tree[x].max
struct node{
int ch[2], siz, fa;
int val, max; //伸展树里存的是队列的顺序
}tree[N];
int tot, root;
void Newnode(int &id, int fa, int val, int siz = 1){
node E={0,0,siz,fa,val,val};
id = tot++;
tree[id] = E;
}
void push_down(int id){}
void push_up(int id){
Size(id) = Size(L(id)) + Size(R(id)) + 1;
Max(id) = max( max(Max(L(id)), Max(R(id))), Val(id));
}
void Rotate(int id, int kind){
int y = Father(id);
push_down(y); push_down(id);
tree[y].ch[kind^1] = tree[id].ch[kind];
Father(tree[id].ch[kind]) = y;
if(Father(y))
tree[Father(y)].ch[R(Father(y))==y] = id;
Father(id) = Father(y);
Father(y) = id;
tree[id].ch[kind] = y;
push_up(y);
}
void Splay(int id, int goal){
push_down(id);
while(Father(id) != goal)
{
int y = Father(id);
if(Father(y) == goal)
Rotate(id, L(y) == id);
else
{
int kind = L(Father(y)) == y;
if(tree[y].ch[kind]==id)
{
Rotate(id, kind^1);
Rotate(id, kind);
}
else
{
Rotate(y, kind);
Rotate(id, kind);
}
}
}
push_up(id);
if(goal == 0)root = id;
}
void Insert(int &id, int val, int siz, int father){ //把值为val的点插到goal点后面
if(id == 0) {
Newnode(id, father, val);
return ;
}
if(val < Max(R(id)) || val < Val(id) || siz < Size(R(id)))
Insert(R(id), val, siz, id);
else
Insert(L(id), val, siz-Size(R(id))-1, id);
push_up(id);
} void init(){
//初始化0这个点
Father(0) = L(0) = R(0) = Size(0) = 0;
Val(0) = 0;
//默认1为最左端点
tot = 1;
Newnode(root, 0, inf);
Newnode(R(root), root, -1);
push_up(root);
}
map<int,int>mp; void put(ll id){
if(L(id))
put(L(id));
if(id > 2)
printf("%d ",mp[Val(id)]);
if(R(id))
put(R(id));
}
int main(){
ll i, u, v, n, id;
while(cin>>n){
mp.clear();
init();
for(i = 1; i <= n; i++) {
scanf("%d %d", &u, &v);
Insert(root, u, v, 0);
Splay(tot-1, 0);
mp[u] = i;
}
put(root); puts("");
}
return 0;
}
/*
2
1 0
2 1 3
1 3
2 3
3 3 5
2 3
1 4
4 3
3 1
5 2 1
1 0 4
4 1
2 2
1 3
3 2 4
4 1
2 2
1 3
3 1 4
4 1
2 2
1 3
3 0 4
1 0
2 1
3 2
4 3 4
1 0
2 1
4 2
3 3 5
1 0
2 1
4 2
3 3
5 2 6
1 0
2 1
4 2
3 3
5 2
6 4 7
2 2
3 4
5 1
7 2
6 5
1 0
4 1 ans:
1 4 2 3
1 2 4 3
1 2 3 4
4 3 2 1
3 4 2 1
3 4 5 2 1
3 6 4 5 2 1
2 4 5 3 1 7 6 */

最新文章

  1. hello,world!
  2. iOS 支付 [支付宝、银联、微信](转载)
  3. IP定位 C#
  4. C++语言笔记系列之十二——C++的继承
  5. Light OJ 1006 - Hex-a-bonacci
  6. Jquery实现的几款漂亮的时间轴
  7. 关于字符latin capital letter sharp s &quot;&#223;&quot;( U+1E9E)显示的问题
  8. html的特点及结构
  9. Erlang cowboy http request生命周期
  10. nodejs服务端使用jquery操作Dom
  11. Jboss解决只能通过localhost访问而不能使用IP访问项目的问题
  12. p2739 Shuttle Puzzle
  13. Jmeter 录制脚本(一)
  14. CSS控制Span强制换行亲测
  15. 浅谈session测试
  16. virgo-tomcat访问日志的详细配置
  17. mybatis框架入门程序:演示通过mybatis实现数据库的删除操作
  18. 四川oi 萌萌哒 (分层并查集)
  19. java线程总结(1/5)
  20. linux中一些常用的命令总结

热门文章

  1. Topcoder 刷题之路_鶸的奋斗
  2. Strobogrammatic Number II -- LeetCode
  3. luogu P1577 切绳子
  4. 每天一个linux命令1之scp
  5. 1.NFC入门
  6. select 下拉框的选中项的change事件
  7. Redis的数据类型之String
  8. django模型manager学习记录
  9. Unicode类别
  10. Java多线程——线程安全问题