hdu3436 Queue-jumpers(Splay)
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3411 Accepted Submission(s): 923
line initially. Each time you should simulate one of the following operations:
1. Top x :Take person x to the front of the queue
2. Query x: calculate the current position of person x
3. Rank x: calculate the current person at position x
Where x is in [1, N].
Ponyo is so clever that she plays the game very well while Garfield has no idea. Garfield is now turning to you for help.
In each case, the first line contains two integers N(1<=N<=10^8), Q(1<=Q<=10^5). Then there are Q lines, each line contain an operation as said above.
9 5
Top 1
Rank 3
Top 7
Rank 6
Rank 8
6 2
Top 4
Top 5
7 4
Top 5
Top 2
Query 1
Rank 6
3
5
8
Case 2:
Case 3:
3
6
题意:给你一个长为n的序列,第i个数的编号是i,有3个操作,1:把编号为x的数放到序列最前面;2:询问编号为x的数的位置;3:询问第x个位置上的数的编号。
思路:因为n很大(1e8)所以要先离散化,我们把询问的数字都保存下来,变为一个号数的区间 ,然后其他区间都缩成一个点,那么区间的长度最大就为2*10^5了。然后我们先按照位置建立splay,接着就是是play的经典操作了。
下面写了两种程序,第一种是每次找到编号x的数对应的节点,然后再算,第二种是预先用map映射编号x对应的节点,本质是一样的。
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<string>
#include<bitset>
#include<algorithm>
using namespace std;
#define lson th<<1
#define rson th<<1|1
typedef long long ll;
typedef long double ldb;
#define inf 99999999
#define pi acos(-1.0)
#define maxn 200050
#define Key_value ch[ch[root][1]][0]
pair<int,int>question[maxn];
int tot,pos[maxn],s[maxn],e[maxn],qishi[maxn];
int t;
int cnt,rt;
int pre[maxn],ch[maxn][2],sz[maxn],num[maxn];
void Treaval(int x) {
if(x) {
Treaval(ch[x][0]);
printf("结点%2d:左儿子 %2d 右儿子 %2d 父结点 %2d size = %2d , num= %2d \n",x,ch[x][0],ch[x][1],pre[x],sz[x],num[x]);
Treaval(ch[x][1]);
}
}
void debug() {printf("%d\n",rt);Treaval(rt);}
void newnode(int &x,int father,int qujian)
{
x=qujian; //为了方便,这里树上节点的编号就是区间的编号
pre[x]=father;ch[x][0]=ch[x][1]=0;
sz[x]=num[x]=e[x]-s[x]+1;
}
void pushup(int x)
{
sz[x]=sz[ch[x][0] ]+sz[ch[x][1] ]+num[x];
}
void build(int &x,int l,int r,int father)
{
if(l>r)return;
int mid=(l+r)/2;
newnode(x,father,mid);
build(ch[x][0],l,mid-1,x);
build(ch[x][1],mid+1,r,x);
pushup(x);
}
void init()
{
cnt=rt=0;
pre[rt]=ch[rt][0]=ch[rt][1]=sz[rt]=0;
build(rt,1,t,0);
}
void rotate(int x,int p)
{
int y=pre[x];
ch[y][!p]=ch[x][p];
pre[ch[x][p] ]=y;
if(pre[y])ch[pre[y] ][ch[pre[y] ][1]==y ]=x;
pre[x]=pre[y];
ch[x][p]=y;
pre[y]=x;
pushup(y);pushup(x);
}
void splay(int x,int goal)
{
while(pre[x]!=goal){
if(pre[pre[x] ]==goal){
rotate(x,ch[pre[x]][0]==x);
}
else{
int y=pre[x];int z=pre[y];
int p=ch[pre[y] ][0]==y;
if(ch[y][p]==x )rotate(x,!p);
else rotate(y,p);
rotate(x,p);
}
}
if(goal==0)rt=x;
pushup(x);
}
int get_kthjiedian(int &x,int k)
{
int t1=sz[ch[x][0] ]+1;
int t2=sz[ch[x][0] ]+num[x];
if(k>=t1 && k<=t2)return x;
if(k<t1)return get_kthjiedian(ch[x][0],k);
if(k>t2)return get_kthjiedian(ch[x][1],k-t2 );
}
int get_min(int r)
{
while(ch[r][0])
{
r = ch[r][0];
}
return r;
}
int get_kthweizhi(int r,int k)
{
int t = sz[ch[r][0]];
if(k <= t)return get_kthweizhi(ch[r][0],k);
else if(k <= t + num[r]) return s[r] + k - t - 1;
else return get_kthweizhi(ch[r][1],k - t - num[r]);
}
void del()
{
if(ch[rt][0]==0 ){
rt=ch[rt][1];
pre[rt]=0;
}
else{
int y=ch[rt][0];
int x=ch[rt][1];
while(ch[y][1]){
y=ch[y][1];
}
splay(y,rt);
ch[y][1]=x;
pre[x]=y;
rt=y;
pre[rt]=0;
pushup(rt);
}
}
int bin(int x)
{
int l = 1, r = t;
while(l <= r)
{
int mid = (l+r)/2;
if(s[mid] <= x && x <= e[mid])return mid;
if(x < s[mid])r = mid-1;
else l = mid+1;
}
return -1;
}
int main()
{
int n,m,i,j,T,c,d,cas=0;
char str[10];
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
tot=0;
for(i=1;i<=m;i++){
scanf("%s%d",str,&c);
if(str[0]=='T')question[i]=make_pair(1,c);
else if(str[0]=='Q')question[i]=make_pair(2,c);
else question[i]=make_pair(3,c);
pos[++tot]=c;
}
pos[++tot]=1;pos[++tot]=n;
sort(pos+1,pos+1+tot);
tot=unique(pos+1,pos+1+tot)-pos-1;
s[1]=e[1]=pos[1];
t=1;
for(i=2;i<=tot;i++){
if(pos[i]-pos[i-1]>1){
t++;s[t]=pos[i-1]+1;e[t]=pos[i]-1;
}
t++;s[t]=e[t]=pos[i];
}
init();
int qujian;
printf("Case %d:\n",++cas);
for(i=1;i<=m;i++){
c=question[i].first;d=question[i].second;
if(c==1){
int r=bin(d);
splay(r,0);
del();
splay(get_min(rt),0); //这里必须直接把删除的节点放到根节点上,不然会T额。。
ch[r][0] = 0;
ch[r][1] = rt;
pre[rt] = r;
rt = r;
pre[rt] = 0;
num[rt]=e[rt]-s[rt]+1;
pushup(rt);
}
if(c==2){
qujian=bin(d);
splay(qujian,0);
printf("%d\n",sz[ch[rt][0] ]+1);
}
else if(c==3){
printf("%d\n",get_kthweizhi(rt,d));
}
}
}
return 0;
}
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<string>
#include<bitset>
#include<algorithm>
using namespace std;
#define lson th<<1
#define rson th<<1|1
typedef long long ll;
typedef long double ldb;
#define inf 99999999
#define pi acos(-1.0)
#define maxn 900050
#define Key_value ch[ch[root][1]][0]
pair<int,int>question[maxn];
int tot,pos[maxn],s[maxn],e[maxn],qishi[maxn];
int t;
map<int,int>mp;
map<int,int>::iterator it;
int cnt,rt;
int pre[maxn],ch[maxn][2],sz[maxn],num[maxn];
void Treaval(int x) {
if(x) {
Treaval(ch[x][0]);
printf("结点%2d:左儿子 %2d 右儿子 %2d 父结点 %2d size = %2d , num= %2d \n",x,ch[x][0],ch[x][1],pre[x],sz[x],num[x]);
Treaval(ch[x][1]);
}
}
void debug() {printf("%d\n",rt);Treaval(rt);}
void newnode(int &x,int father)
{
x=++cnt;
pre[x]=father;ch[x][0]=ch[x][1]=0;
}
void pushup(int x)
{
sz[x]=sz[ch[x][0] ]+sz[ch[x][1] ]+num[x];
}
void build(int &x,int l,int r,int father)
{
if(l>r)return;
int mid=(l+r)/2;
newnode(x,father);
sz[cnt]=num[cnt]=e[mid]-s[mid]+1;
qishi[cnt]=s[mid];
if(num[cnt]==1)mp[s[mid]]=cnt;
build(ch[x][0],l,mid-1,x);
build(ch[x][1],mid+1,r,x);
pushup(x);
}
void init()
{
cnt=rt=0;
pre[rt]=ch[rt][0]=ch[rt][1]=sz[rt]=0;
build(rt,1,t,0);
}
void rotate(int x,int p)
{
int y=pre[x];
ch[y][!p]=ch[x][p];
pre[ch[x][p] ]=y;
if(pre[y])ch[pre[y] ][ch[pre[y] ][1]==y ]=x;
pre[x]=pre[y];
ch[x][p]=y;
pre[y]=x;
pushup(y);pushup(x);
}
void splay(int x,int goal)
{
while(pre[x]!=goal){
if(pre[pre[x] ]==goal){
rotate(x,ch[pre[x]][0]==x);
}
else{
int y=pre[x];int z=pre[y];
int p=ch[pre[y] ][0]==y;
if(ch[y][p]==x )rotate(x,!p);
else rotate(y,p);
rotate(x,p);
}
}
if(goal==0)rt=x;
pushup(x);
}
int get_kthjiedian(int &x,int k)
{
int t1=sz[ch[x][0] ]+1;
int t2=sz[ch[x][0] ]+num[x];
if(k>=t1 && k<=t2)return x;
if(k<t1)return get_kthjiedian(ch[x][0],k);
if(k>t2)return get_kthjiedian(ch[x][1],k-t2 );
}
int get_kthweizhi(int &x,int k)
{
int t1=sz[ch[x][0] ]+1;
int t2=sz[ch[x][0] ]+num[x];
if(k>=t1 && k<=t2){
int ans=qishi[x]+k-t1;
splay(x,0);
return ans;
}
else if(k<t1)return get_kthweizhi(ch[x][0],k);
else return get_kthweizhi(ch[x][1],k-t2 );
}
void del()
{
if(ch[rt][0]==0 ){
rt=ch[rt][1];
pre[rt]=0;
}
else{
int y=ch[rt][0];
int x=ch[rt][1];
while(ch[y][1]){
y=ch[y][1];
}
splay(y,rt);
ch[y][1]=x;
pre[x]=y;
rt=y;
pre[rt]=0;
pushup(rt);
}
}
int get_min(int x)
{
int r=x;
while(ch[r][0]){
r=ch[r][0];
}
return r;
}
int main()
{
int n,m,i,j,T,c,d,cas=0;
char str[10];
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
tot=0;
for(i=1;i<=m;i++){
scanf("%s%d",str,&c);
if(str[0]=='T')question[i]=make_pair(1,c);
else if(str[0]=='Q')question[i]=make_pair(2,c);
else question[i]=make_pair(3,c);
pos[++tot]=c;
}
pos[++tot]=1;pos[++tot]=n;
sort(pos+1,pos+1+tot);
tot=unique(pos+1,pos+1+tot)-pos-1;
s[1]=e[1]=pos[1];
t=1;
for(i=2;i<=tot;i++){
if(pos[i]-pos[i-1]>1){
t++;s[t]=pos[i-1]+1;e[t]=pos[i]-1;
}
t++;s[t]=e[t]=pos[i];
}
init();
printf("Case %d:\n",++cas);
for(i=1;i<=m;i++){
c=question[i].first;d=question[i].second;
if(c==1){
int geshu=num[mp[d] ];
int kaishi=qishi[mp[d] ];
splay(mp[d],0);
del();
splay(get_min(rt),0 );
cnt++;
qishi[cnt]=kaishi;
pre[cnt]=0;num[cnt]=geshu;
pre[rt]=cnt;
ch[cnt][0]=0;ch[cnt][1]=rt;
rt=cnt;
mp[d]=cnt;
pushup(rt);
}
if(c==2){
splay(mp[d],0);
printf("%d\n",sz[ch[rt][0] ]+1);
}
else if(c==3){
printf("%d\n",get_kthweizhi(rt,d));
}
}
}
return 0;
}
hdu3436 Queue-jumpers(Splay)的更多相关文章
- POJ - 3481 splay板子
Double Queue 默写splay板子 很多细节问题... #include<cstdio> #include<iostream> using namespace std ...
- HDU-3436 Queue-jumpers 树状数组 | Splay tree删除,移动
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3436 树状数组做法<猛戳> Splay tree的经典题目,有删除和移动操作.首先要离散化 ...
- 【POJ3481】【splay】Double Queue
Description The new founded Balkan Investment Group Bank (BIG-Bank) opened a new office in Bucharest ...
- POJ 3481Double Queue Splay
#include<stdio.h> #include<string.h> ; ],data[N],id[N],fa[N],size,root; void Rotate(int ...
- HDU 4441 Queue Sequence(splay)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4441 题意:一个数列,三种操作:(1)插入:找到没在当前数列中的最小的正整数i,将其插在位置p之后,并 ...
- codeforces 38G - Queue splay伸展树
题目 https://codeforces.com/problemset/problem/38/G 题意: 一些人按顺序进入队列,每个人有两个属性,地位$A$和能力$C$ 每个人进入时都在队尾,并最多 ...
- POJ-3481 Double Queue (splay)
The new founded Balkan Investment Group Bank (BIG-Bank) opened a new office in Bucharest, equipped w ...
- HDU 3436 Queue-jumpers (splay tree)
Queue-jumpers Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tot ...
- 【splay】文艺平衡树 BZOJ 3223
Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 ...
随机推荐
- 直播预告 | 开源的云原生开发环境 —— Nocalhost
直播来啦!本次云原生学院邀请到腾讯云 CODING DevOps 后端工程师王炜为大家分享<开源的云原生开发环境 -- Nocalhost>. 直播信息 讲师:王炜 - 腾讯云 CODIN ...
- 新蜂商城的mybatis plus版本,添加了秒杀专区、优惠卷领取以及后台搜索功能
本项目是在newbee-mall项目的基础上改造而来,将orm层由mybatis替换为mybatis-plus,添加了秒杀功能.优惠劵功能以及后台搜索功能,喜欢的话麻烦给我个star 后台管理模块添加 ...
- ASP.NET Core中的数据保护
在这篇文章中,我将介绍ASP.NET Core 数据保护系统:它是什么,为什么我们需要它,以及它如何工作. 为什么我们需要数据保护系统? 数据保护系统是ASP.NET Core使用的一组加密api.加 ...
- LeetCode200 岛屿的个数
给定一个由 '1'(陆地)和 '0'(水)组成的的二维网格,计算岛屿的数量.一个岛被水包围,并且它是通过水平方向或垂直方向上相邻的陆地连接而成的.你可以假设网格的四个边均被水包围. 示例 1: 输入: ...
- Redis实战篇(一)搭建Redis实例
今天是Redis实战系列的第一讲,先从如何搭建一个Redis实例开始. 下面介绍如何在Docker.Windows.Linux下安装. Docker下安装 1.查看可用的 Redis 版本 访问 Re ...
- 搭建docker环境,安装常用应用(单机)
## 安装docker ```bash1.卸载系统之前dockersudo yum remove docker \ docker-client \ docker-client-latest \ doc ...
- 不要把file,process或者super权限授予管理员以外的账号
file权限的主要作用是通过select ....into outfile 写到服务器上具有写权限的目录下,作为文本格式存放,具有权限的目录也就是启动mysql时的用户权限目录.(没有理解) 可以将有 ...
- iconv函数报错 Detected an illegal character in input string
近日使用php代码导出文件为excel,一直乱码.导出修改编码都无效,最后发现,是需要修改php导出代码本身的编码.首先用记事本打开php代码,另存为,选择ANSI格式.然后打开iconv函数这个ph ...
- 【Linux】if中的逻辑运算符怎么在linux的帮助中看到
今天在写shell的时候,突然想查看下if相关的一些逻辑运算的,像-f -d之类的这种 于是man if 或者if --help 可是返回的信息却都无济于事,一点帮助都没有 回想一下,if中调的判断 ...
- 记一次 RocketMQ broker 因内存不足导致的启动失败
原创:西狩 编写日期 / 修订日期:2020-01-12 / 2020-01-12 版权声明:本文为博主原创文章,遵循 CC BY-SA-4.0 版权协议,转载请附上原文出处链接和本声明. 背景 该小 ...