hdu 3436 splay树+离散化*
Queue-jumpers
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3139 Accepted Submission(s): 848
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
/*
hdu 3436 splay树+离散化*
本来以为很好做的,写到中途发现10^8,GG
然后参考了下,把操作不用的区间缩点离散化处理
然后就是删除点,感觉自己开始写的太麻烦了,将要删除的点移动到根,如果没有儿子直接删掉,
否则将右树的最小点移到ch[r][1]使右树没有左子树,然后把根的左树接到右树上
hhh-2016-02-20 22:22:22
*/ #include <functional>
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <map>
#include <cmath>
using namespace std;
typedef long long ll;
typedef long double ld;
#define key_value ch[ch[root][1]][0]
const int maxn = 200010; int ch[maxn][2];
int pre[maxn],key[maxn],siz[maxn],num[maxn]; int root,tot,cnt,n,TOT;
int posi[maxn];
char qry[maxn][10];
int op[maxn];
int te[maxn];
int s[maxn],e[maxn]; void Treaval(int x) {
if(x) {
Treaval(ch[x][0]);
printf("结点%2d:左儿子 %2d 右儿子 %2d 父结点 %2d size = %2d ,key = %2d num= %2d \n",x,ch[x][0],ch[x][1],pre[x],siz[x],key[x],num[x]);
Treaval(ch[x][1]);
}
}
void debug() {printf("%d\n",root);Treaval(root);} void push_up(int r)
{
int lson = ch[r][0],rson = ch[r][1];
siz[r] = siz[lson] + siz[rson] + num[r];
} void push_down(int r)
{ } void inOrder(int r)
{
if(!r)return;
inOrder(ch[r][0]);
printf("%d ",key[r]);
inOrder(ch[r][1]);
} void NewNode(int &r,int far,int k)
{
r = ++tot;
posi[k] = r;
key[r] = k;
pre[r] = far;
ch[r][0] = ch[r][1] = 0;
siz[r] = num[r] = e[k]-s[k]+1;
} void rotat(int x,int kind)
{
int y = pre[x];
push_down(y);
push_down(x);
ch[y][!kind] = ch[x][kind];
pre[ch[x][kind]] = y;
if(pre[y])
ch[pre[y]][ch[pre[y]][1]==y] = x;
pre[x] = pre[y];
ch[x][kind] = y;
pre[y] = x;
push_up(y);
} void build(int &x,int l,int r,int far)
{
if(l > r) return ;
int mid = (l+r) >>1;
NewNode(x,far,mid);
build(ch[x][0],l,mid-1,x);
build(ch[x][1],mid+1,r,x);
push_up(x);
} void splay(int r,int goal)
{
push_down(r);
while(pre[r] != goal)
{
if(pre[pre[r]] == goal)
{
push_down(pre[r]);
push_down(r);
rotat(r,ch[pre[r]][0] == r);
}
else
{
push_down(pre[pre[r]]);
push_down(pre[r]);
push_down(r);
int y = pre[r];
int kind = ch[pre[y]][0] == y;
if(ch[y][kind] == r)
{
rotat(r,!kind);
rotat(r,kind);
}
else
{
rotat(y,kind);
rotat(r,kind);
}
}
}
push_up(r);
if(goal == 0)
root = r;
} int Bin(int x)
{
int l = 0,r = TOT-1;
while(l<=r)
{
int mid=(l+r)>>1;
if(s[mid]<=x&&e[mid]>=x)
return mid;
if(e[mid]<x)
l=mid+1;
else
r=mid-1;
}
} int get_min(int r)
{
push_down(r);
while(ch[r][0])
{
r = ch[r][0];
push_down(r);
}
return r;
} int get_kth(int r,int k)
{
int t = siz[ch[r][0]];
if(k<=t)
return get_kth(ch[r][0],k);
else if(k<=t+num[r])
return s[key[r]]+(k-t)-1;
else
return get_kth(ch[r][1],k-t-num[r]);
} void delet()
{
if(ch[root][0] == 0 || ch[root][1] == 0)
{
root = ch[root][0] + ch[root][1];
pre[root] = 0;
return;
}
int k = get_min(ch[root][1]);
splay(k,root);
ch[ch[root][1]][0] = ch[root][0];
root = ch[root][1];
pre[ch[root][0]] = root;
pre[root] = 0;
push_up(root);
} int top(int t)
{
int r = Bin(t);
r = posi[r];
splay(r,0);
delet();
splay(get_min(root),0);
ch[r][0] = 0;
ch[r][1] = root;
pre[root] = r;
root = r;
pre[root] = 0;
push_up(root);
// debug();
} int Query(int x)
{
int r = Bin(x);
r = posi[r];
splay(r,0);
return siz[ch[r][0]]+1;
} int get_rank(int x,int k)
{
int t = siz[ch[x][0]];
if(k <= t)
return get_rank(ch[x][0],k);
else
return get_rank(ch[x][1],k-t);
} void ini(int n)
{
tot = root = 0;
ch[root][0] = ch[root][1] = pre[root] = siz[root] = num[root] = 0 ;
build(root,0,n-1,0); push_up(ch[root][1]);
push_up(root);
//inOrder(root);
} int main()
{
int q,T;
int cas =1;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&q) ;
if(n == -1 && q == -1)
break; int tcn = 0;
printf("Case %d:\n",cas++);
for(int i =1; i <= q; i++)
{
scanf("%s%d",qry[i],&op[i]);
if(qry[i][0] == 'T' || qry[i][0] == 'Q')
te[tcn++] = op[i];
}
te[tcn++] = n;
te[tcn++] = 1;
sort(te,te+tcn);
TOT= 0;
s[TOT] = te[0],e[TOT] = te[0],TOT++;
for(int i = 1; i < tcn; i++)
{
if(te[i] != te[i-1] && i)
{
if(te[i] - te[i-1] > 1)
{
s[TOT] = te[i-1]+1;
e[TOT] = te[i]-1;
TOT++;
}
s[TOT] = te[i];
e[TOT] = te[i];
TOT++;
}
}
ini(TOT);
//debug();
for(int i = 1; i <= q; i++)
{
if(qry[i][0]=='T')
top(op[i]);
else if(qry[i][0]=='Q')
printf("%d\n", Query(op[i]));
else
printf("%d\n",get_kth(root,op[i]));
}
//debug();
}
return 0;
}
hdu 3436 splay树+离散化*的更多相关文章
- hdu 3436 线段树 一顿操作
Queue-jumpers Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) To ...
- hdu 1890 splay树
Robotic Sort Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tot ...
- ZOJ 2301/HDU 1199 线段树+离散化
给这个题目跪了两天了,想吐简直 发现自己离散化没学好 包括前一个离散化的题目,实际上是错了,我看了sha崽的博客后才知道,POJ那题简直数据弱爆了,本来随便一组就能让我WA掉的,原因在于离散化的时候, ...
- hdu 5792 线段树+离散化+思维
题目大意: Given a sequence A with length n,count how many quadruple (a,b,c,d) satisfies: a≠b≠c≠d,1≤a< ...
- HDU 1542 线段树离散化+扫描线 平面面积计算
也是很久之前的题目,一直没做 做完之后觉得基本的离散化和扫描线还是不难的,由于本题要离散x点的坐标,最后要计算被覆盖的x轴上的长度,所以不能用普通的建树法,建树建到r-l==1的时候就停止,表示某段而 ...
- HDU 4288 线段树+离散化
题意: n个操作 在[1, 100000] 的区间上add 或del数( 必不会重复添加或删除不存在的数) sum 求出整个集合中 (下标%5 == 3 位置) 的数 的和 注意数据类型要64位 ...
- HDU 5862 Counting Intersections(离散化+树状数组)
HDU 5862 Counting Intersections(离散化+树状数组) 题目链接http://acm.split.hdu.edu.cn/showproblem.php?pid=5862 D ...
- Splay树学习
首先给出一论文讲的很好: http://www.docin.com/p-63165342.html http://www.docin.com/p-62465596.html 然后给出模板胡浩大神的模板 ...
- 1439. Battle with You-Know-Who(splay树)
1439 路漫漫其修远兮~ 手抄一枚splay树 长长的模版.. 关于spaly树的讲解 网上很多随手贴一篇 貌似这题可以用什么bst啦 堆啦 平衡树啦 等等 这些本质都是有共同点的 查找.删除特 ...
随机推荐
- 使用ArrayList时代码内部发生了什么(jdk1.7)?
前言 ArrayList(这里的ArrayList是基于jdk1.7)是在项目中经常使用的集合类,例如我们从数据库中查询出一组数据.这篇文章不去剖析它的继承和实现,只是让我们知道实例化及增删改查时它的 ...
- v7000数据恢复_MDisk重建数据恢复方法(北亚数据恢复)
很多工程师都有这样的疑问,MDisk重建后还能不能恢复数据呢?应该怎么做才能恢复数据呢?本文这里就以IBM V7000存储为例,详细讲解因为某个MDisk被重建导致的数据丢失的恢复方法.我们本案例中的 ...
- JAVA_SE基础——15.循环嵌套
嵌套循环是指在一个循环语句的循环体中再定义一个循环语句结构,while,do-while,for循环语句都可以进行嵌套,并且可以互相嵌套,下面来看下for循环中嵌套for循环的例子. 如下: publ ...
- ASP.NET MVC中错误处理方式
/// <summary> /// 标记了HandleError,并指明错误处理页为AboutError.aspx /// </summary> /// <returns ...
- 帧动画的创建方式 - 纯Java代码方式
废话不多说,先看东西 帧动画的创建方式主要以下2种: * 用xml创建动画: * 纯Java代码创建动画: 本文内容主要关注 纯java代码创建帧动画 的方式: 用xml创建帧动画:http:// ...
- hadoop2.7.3+spark2.1.0+scala2.12.1环境搭建(1)安装jdk
一.文件准备 下载jdk-8u131-linux-x64.tar.gz 二.工具准备 2.1 Xshell 2.2 Xftp 三.操作步骤 3.1 解压文件: $ tar zxvf jdk-8u131 ...
- python当中的 可迭代对象 迭代器
学习python有一段时间了,在学习过程中遇到很多难理解的东西,做一下总结,希望能对其他朋友有一些帮助. 完全是个人理解,难免有错,欢迎其他大神朋友们批评指正. 1 迭代 什么是迭代呢??我们可以这样 ...
- Python基础-用户验证
一.项目需求 1.根据用户名和密码,验证用户是否可登陆 2.允许一次执行可验证三次 3.当用户名输错三次后,该用户名锁定,永久不可登陆 二.代码如下 #!/usr/bin/env python #-* ...
- oracle批量插入优化方案
今天听DBA说如果从一个表批量查询出一批数据之后批量插入另外一张表的优化方案: 1)不写归档日志: 2)采用独占 关于insert /*+ append */我们需要注意以下三点: a.非归档模式下, ...
- DBSCAN
DBSCAN,英文全写为Density-based spatial clustering of applications with noise ,是在 1996 年由Martin Ester, Han ...