hdu 3436 线段树 一顿操作
Queue-jumpers
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3348 Accepted Submission(s): 904
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.
Sample Input
3
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
Sample Output
Case 1:
3
5
8
Case 2:
Case 3:
3
6
/*
hdu 3436 线段树 一顿操作 这个题以前用splay树做过,但是最近练习线段树中(据说线段树能解决splay树中的很多操作)
Top: 将第x个数移动到队首
Query: 查询x的位置
Rank: 找出排第x的数 top想的数之间在线段树前面预留一部分,于是线段树最多需要2e5.对于Rank可以直接查找
主要是对于Query没想到什么办法.最后直接是用数组来保存每个数的位置,然后利用求和便能得到
某数在这个队列中的位置 hhh-2016-04-12 19:20:16
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <functional>
typedef long long ll;
#define lson (i<<1)
#define rson ((i<<1)|1)
using namespace std; const int maxn = 1e6+10; struct node
{
int l,r;
int sum,val;
int mid()
{
return (l+r)>>1;
}
} tree[maxn<<2];
int T,n,m;
int a[maxn];
int ano[maxn];
int st[maxn],en[maxn];
int pos[maxn];
char op[maxn][6];
int tot,TOT; void push_up(int i)
{
tree[i].sum = tree[lson].sum + tree[rson].sum;
} void build(int i ,int l,int r)
{
tree[i].l =l ,tree[i].r = r;
tree[i].sum = 0;
tree[i].val = 0;
if(l == r)
{
if(tree[i].l > m)
{
int t = tree[i].l-m;
tree[i].val = t;
tree[i].sum = en[t]-st[t]+1;
}
return ;
}
int mid = tree[i].mid();
build(lson,l,mid);
build(rson,mid+1,r);
push_up(i);
} void push_down(int i)
{ } void update(int i,int k,int val)
{
if(tree[i].l == tree[i].r )
{
if(!val) tree[i].sum = 0,tree[i].val = 0;
else tree[i].sum = en[val]-st[val]+1,tree[i].val = val;
return ;
}
int mid = tree[i].mid();
if(k <= mid)
update(lson,k,val);
else
update(rson,k,val);
push_up(i);
} int sum(int i,int l,int r)
{
if(tree[i].l>=l && tree[i].r <= r)
return tree[i].sum;
int mid = tree[i].mid();
int su = 0;
if(l <= mid)
su += sum(lson,l,r);
if(r > mid)
su += sum(rson,l,r);
push_up(i);
return su;
} int get_k(int i,int k)
{
if(tree[i].l == tree[i].r && k <= en[tree[i].val]-st[tree[i].val]+1)
return st[tree[i].val]+k-1;
int mid = tree[i].mid(); if(k <= tree[lson].sum)
return get_k(lson,k);
else
return get_k(rson,k-tree[lson].sum);
push_up(i);
} int bin(int key)
{
int l = 1,r = tot-1;
while(l <= r)
{
int mid = (l+r)>>1;
if(st[mid]<=key && en[mid]>=key)
return mid;
else if(key < st[mid])
r = mid - 1;
else
l = mid + 1;
}
} int main()
{
int cas = 1;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
tot = 0;
for(int i = 1; i <= m; i++)
{
scanf("%s%d",op[i],&a[i]);
if(op[i][0] == 'T' || op[i][0] == 'Q')
ano[tot++] = a[i];
}
ano[tot++] = 1,ano[tot++] = n;
sort(ano,ano+tot);
// for(int i = 0;i < tot;i++)
// cout << ano[i] <<" ";
// cout << endl;
TOT = tot;
tot = 1;
st[tot] = ano[0],en[tot] = ano[0];
tot++;
printf("Case %d:\n",cas++);
for(int i = 1; i < TOT; i++)
{
if(ano[i] != ano[i-1])
{
if(ano[i] - ano[i-1] > 1)
{
st[tot] = ano[i-1]+1;
en[tot++] = ano[i]-1;
}
st[tot] = ano[i];
en[tot] = ano[i];
tot++;
}
}
// for(int i = 1;i < tot;i++)
// cout <<st[i] << " "<<en[i] <<endl;
build(1,1,m+tot-1);
memset(ano,0,sizeof(ano));
int cur = m;
for(int i = 1; i <= m; i++)
{
int tp = bin(a[i]);
//cout << "val:" << a[i] << " "<<tp<<endl;
if(op[i][0] == 'T')
{
if(ano[tp])
{
update(1,pos[tp],0);
update(1,cur,tp);
pos[tp] = cur;
cur --;
}
else
{
update(1,m+tp,0);
update(1,cur,tp);
pos[tp] = cur;
cur--;
ano[tp] = 1;
}
}
else if(op[i][0] == 'Q')
{
if(ano[tp])
{
printf("%d\n",sum(1,1,pos[tp]));
}
else
{
printf("%d\n",sum(1,1,m+tp));
}
}
else
{
printf("%d\n",get_k(1,a[i]));
}
}
}
return 0;
}
hdu 3436 线段树 一顿操作的更多相关文章
- hdu 2871 线段树(各种操作)
Memory Control Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) T ...
- hdu 3974 线段树 将树弄到区间上
Assign the task Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- hdu 3397 线段树双标记
Sequence operation Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Othe ...
- hdu 4578 线段树(标记处理)
Transformation Time Limit: 15000/8000 MS (Java/Others) Memory Limit: 65535/65536 K (Java/Others) ...
- hdu 4267 线段树间隔更新
A Simple Problem with Integers Time Limit: 5000/1500 MS (Java/Others) Memory Limit: 32768/32768 K ...
- hdu 1754 线段树(Max+单点修改)
I Hate It Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...
- hdu 3436 splay树+离散化*
Queue-jumpers Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) To ...
- Can you answer these queries? HDU 4027 线段树
Can you answer these queries? HDU 4027 线段树 题意 是说有从1到编号的船,每个船都有自己战斗值,然后我方有一个秘密武器,可以使得从一段编号内的船的战斗值变为原来 ...
- 线段树区间更新操作及Lazy思想(详解)
此题题意很好懂: 给你N个数,Q个操作,操作有两种,‘Q a b ’是询问a~b这段数的和,‘C a b c’是把a~b这段数都加上c. 需要用到线段树的,update:成段增减,query:区间求 ...
随机推荐
- 2017-2018-1 我爱学Java 第三周 作业
Team Presentation 团队展示 队员学号 队名 团队项目描述 队员风采 团队首次合照 团队的特色描述 团队初步合作 前两周合作过程中的优缺点 如何改进 团队选题 确立,建立和初步熟悉团队 ...
- Linux下vim上编辑实现进度条
1.效果展示: 进度条,先来看一个效果: 这是进度结果,模拟实现了进度条的前进.百分比的现实.以及稍微的动画特效. 2.原理描述: 因为Linux系统下的输出有缓存,如果及时刷新显示,就可以得到我们想 ...
- ord在python是什么意思?
>>> help(ord)Help on built-in function ord in module builtins:ord(...) #这是一个函数 ord(c) -> ...
- NOIP2012 提高组 Day 2
http://www.cogs.pro/cogs/page/page.php?aid=16 期望得分:100+100+0=0 实际得分:100+20+0=120 T2线段树标记下传出错 T1 同余方程 ...
- Python基础学习篇章二
一. Python如何运行程序 1. 在交互模式下编写代码 最简单的运行Python程序的方法是在Python交互命令行中输入程序.当然有很多方法可以开始这样的命令行,比如IDE,系统终端.如果你已经 ...
- 爬虫系列(1)-----python爬取猫眼电影top100榜
对于Python初学者来说,爬虫技能是应该是最好入门,也是最能够有让自己有成就感的,今天在整理代码时,整理了一下之前自己学习爬虫的一些代码,今天先上一个简单的例子,手把手教你入门Python爬虫,爬取 ...
- 用Java语言实现简单的词法分析器
编译原理中的词法分析算是很重要的一个部分,原理比较简单,不过网上大部分都是用C语言或者C++来编写,笔者近期在学习Java,故用Java语言实现了简单的词法分析器. 要分析的代码段如下: 输出结果如下 ...
- Linux实战案例(2)实例讲解使用软连接的场景和过程
=================================== 使用场景:使用软连接简化版本切换动作 进入操作目录, cd /opt/modules/ ==================== ...
- HTML的水平居中和垂直居中解决方案
水平居中:给div设置一个宽度,然后添加margin:0 auto属性 div{ width:200px; margin:0 auto; } 让绝对定位的div居中 div { position: a ...
- 面向对象的PHP(5)
OOP的好处 封装 封装可以隐藏实现细节,使代码模块化,代码重用 继承 继承可以扩展已存在的代码模块(class),代码重用 多态 为了类在继承和派生的时候,保证实例的某一属性正确调用,接口重用 关键 ...