【NOIP2017D2T3】列队
Description
Sylvia 是一个热爱学习的女孩子。
前段时间,Sylvia 参加了学校的军训。众所周知,军训的时候需要站方阵。Sylvia所在的方阵中有n × m名学生,方阵的行数为 n,列数为 m。
为了便于管理,教官在训练开始时,按照从前到后,从左到右的顺序给方阵中的学生从 1 到 n × m 编上了号码(参见后面的样例)。即:初始时,第 i 行第 j 列的学生的编号是(i - 1) × m + j。
然而在练习方阵的时候,经常会有学生因为各种各样的事情需要离队。在一天中,一共发生了 q 件这样的离队事件。每一次离队事件可以用数对(x, y) (1≤x≤n,1≤y≤m)描述,表示第 x 行第 y 列的学生离队。
在有学生离队后,队伍中出现了一个空位。为了队伍的整齐,教官会依次下达这样的两条指令:
1. 向左看齐。这时第一列保持不动,所有学生向左填补空缺。不难发现在这条指令之后,空位在第 x 行第 m 列。
2. 向前看齐。这时第一行保持不动,所有学生向前填补空缺。不难发现在这条指令之后,空位在第 n 行第 m 列。
教官规定不能有两个或更多学生同时离队。即在前一个离队的学生归队之后,下一个学生才能离队。因此在每一个离队的学生要归队时,队伍中有且仅有第 n 行第 m 列一个空位,这时这个学生会自然地填补到这个位置。
因为站方阵真的很无聊,所以 Sylvia 想要计算每一次离队事件中,离队的同学的编号是多少。
注意:每一个同学的编号不会随着离队事件的发生而改变,在发生离队事件后方阵中同学的编号可能是乱序的。
Input
输入文件名为 phalanx.in。
输入共 q+1 行。
第 1 行包含 3 个用空格分隔的正整数 n, m, q,表示方阵大小是 n 行 m 列,一共发生了 q 次事件。
接下来 q 行按照事件发生顺序描述了 q 件事件。每一行是两个整数 x, y,用一个空格分隔,表示这个离队事件中离队的学生当时排在第 x 行第 y 列。
Output
输出文件名为 phalanx.out。
按照事件输入的顺序,每一个事件输出一行一个整数,表示这个离队事件中离队学生的编号。
Sample Input
2 2 3
1 1
2 2
1 2
Sample Output
1
1
4
Hint
线段树
好像是第一次写这种线段树维护区间插入/删除的题(因为听说splay常数大,不敢写)。
首先肯定将第m列与那n行分开维护,一共有n+1颗线段树。
我们首先将对应的节点打上标记,表示该节点并没有改变,当我们需要访问其子区间的时候,将该区间拆成两个。然后询问(x,y)(x,y)(x,y)的时候,假设y!=my!=my!=m,那么就是找第x行的第y个数。否则就是找第m行的第x个数。找数的过程就是线段树上二分,具体来说我们对每个区间要记录一个sizesizesize表示区间内的人数。然后在将对应区间的sizesizesize减少。插入的时候直接插入在区间的最后就行了。
每一行最多n+mn+mn+m个点,所以动态开点上界设在n+mn+mn+m就可以了。
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<ctime>
#include<queue>
#include<iomanip>
#define ll long long
#define N 300005 using namespace std;
inline int Get() {int x=,f=;char ch=getchar();while(ch<''||ch>'') {if(ch=='-') f=-;ch=getchar();}while(''<=ch&&ch<='') {x=(x<<)+(x<<)+ch-'';ch=getchar();}return x*f;} ll n,m,q;
int cnt;
int nxt[N];
const int lx=,rx=N<<;
int rt[N];
int tag[N*],ls[N*],rs[N*],size[N*];
ll id[N*];
void update(int v) {size[v]=size[ls[v]]+size[rs[v]];} void build(int &v,int l,int r) {
if(!v) v=++cnt;
size[v]=r-l+;
if(l==r) id[v]=l;
tag[v]=;
} void pre(int &v,int l,int r,int lx,int rx) {
if(!v) v=++cnt;
if(l>rx||r<lx) return ;
if(l<=lx&&rx<=r) {build(v,lx,rx);return ;}
int mid=lx+rx>>;
pre(ls[v],l,r,lx,mid);
pre(rs[v],l,r,mid+,rx);
update(v);
} void Find(int v,int lx,int rx,int k,ll &pos,ll &g) {
if(lx==rx) {
pos=lx;
g=id[v];
return ;
}
int mid=lx+rx>>;
if(tag[v]) {
build(ls[v],lx,mid);
build(rs[v],mid+,rx);
tag[v]=;
}
if(k>size[ls[v]]) {
Find(rs[v],mid+,rx,k-size[ls[v]],pos,g);
} else {
Find(ls[v],lx,mid,k,pos,g);
}
} void Delete(int v,int lx,int rx,int pos) {
size[v]--;
if(lx==rx) return ;
int mid=lx+rx>>;
if(tag[v]) {
build(ls[v],lx,mid);
build(rs[v],mid+,rx);
tag[v]=;
}
if(pos<=mid) Delete(ls[v],lx,mid,pos);
else Delete(rs[v],mid+,rx,pos);
} void Insert(int &v,int lx,int rx,int pos,ll id) {
if(!v) v=++cnt;
size[v]++;
if(lx==rx) {
::id[v]=id;
return ;
}
int mid=lx+rx>>;
if(tag[v]) {
build(ls[v],lx,mid);
build(rs[v],mid+,rx);
tag[v]=;
}
if(pos<=mid) Insert(ls[v],lx,mid,pos,id);
else Insert(rs[v],mid+,rx,pos,id);
} ll pos,g; void Get_out(ll &nx,ll &ny,ll x,ll y) {
if(y<m) {
Find(rt[x],lx,rx,y,pos,g);
if(pos<=m-) {
nx=x;
ny=pos;
} else {
nx=(g-)/m+;
ny=(g-)%m+;
}
Delete(rt[x],lx,rx,pos);
} else {
Find(rt[n+],lx,rx,x,pos,g);
if(pos<=n) {
nx=pos;
ny=m;
} else {
nx=(g-)/m+;
ny=(g-)%m+;
}
Delete(rt[n+],lx,rx,pos);
}
} int main() {
n=Get(),m=Get(),q=Get();
if(m>) {
for(int i=;i<=n;i++) {
nxt[i]=m;
pre(rt[i],,m-,lx,rx);
}
}
pre(rt[n+],,n,lx,rx);
nxt[n+]=n+;
int x,y;
ll sx,sy;
ll tx,ty;
while(q--) {
x=Get(),y=Get();
if(y<m) {
Get_out(sx,sy,x,y);
Get_out(tx,ty,x,m);
Insert(rt[x],lx,rx,nxt[x],(tx-)*m+ty);
Insert(rt[n+],lx,rx,nxt[n+],(sx-)*m+sy);
nxt[x]++,nxt[n+]++;
} else {
Get_out(sx,sy,x,y);
Insert(rt[n+],lx,rx,nxt[n+],(sx-)*m+sy);
nxt[n+]++;
}
cout<<(sx-)*m+sy<<"\n";
}
return ;
}
【NOIP2017D2T3】列队的更多相关文章
- NOIP2017D2T3 列队—Treap
NOIP2017列队 Description Sylvia 是一个热爱学习的女孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Sylvia所在的方阵中有n × m ...
- 树套树Day2
滚回来更新,,, 在Day1我们学了最基本的线段树套平衡树 Day2开始我们要学习一些黑科技 (所以很大概率会出现Day3 w 1.线段树上的黑科技 这一段我们分几项来讲 1.权值线段树 权值线段树以 ...
- [LuoguP2161[ [SHOI2009]会场预约 (splay)
题面 传送门:https://www.luogu.org/problemnew/show/P2161 Solution splay 的确有线段树/树状数组的做法,但我做的时候脑残没想到 我们可以考虑写 ...
- 关于PHP堆栈与列队
在PHP中数组常被当作堆栈(后进先出:LIFO)与队列(先进先出:FIFO)结构来使用.PHP提供了一组函数可以用于push与pop(堆栈)还有shift与unshift(队列)来操作数组元素.堆栈与 ...
- 在PHP中如何使用消息列队
/** * 消息列队服务 * @author zhou.tingze * @example * -----------------------------------Create----------- ...
- BZOJ2720: [Violet 5]列队春游
2720: [Violet 5]列队春游 Time Limit: 5 Sec Memory Limit: 128 MBSubmit: 173 Solved: 125[Submit][Status] ...
- [NOIp 2017]列队
Description Sylvia 是一个热爱学习的女孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Sylvia 所在的方阵中有$n \times m$名学生, ...
- P2649 - 【NOIP2017】列队
Description Sylvia 是一个热爱学习的女孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Sylvia 所在的方阵中有 n×m 名学生,方阵的行数为 ...
- WebForm应用log4net记录错误日志——使用线程列队写入
我的项目结构如下图: 日志帮助类库需要log4net包:工具—NuGet包管理器—管理解决方案NuGet程序包 线程日志帮助类 FlashLogger.cs 代码 using System; usin ...
随机推荐
- Java 8 新特性-菜鸟教程 (9) -Java8 Base64
Java8 Base64 在Java 8中,Base64编码已经成为Java类库的标准. Java 8 内置了 Base64 编码的编码器和解码器. Base64工具类提供了一套静态方法获取下面三种B ...
- snmp自定义OID与文件下载----服务器端配置
客户端使用命令工具:snmpwalk 服务端开启服务 snmp service.下载安装 net-snmp. 最近做了一些工作,记性较差感觉还是记下来比较好,毕竟网上能查到的有用的资料太少了. 自定义 ...
- 深入React技术栈之初入React世界
1.1 react简介 react并不是完整的MVM/MVVM框架,专注于提供清晰.简洁的View层解决方案. 传统开发模式,要更新页面需要手动操作DOM元素.如图1.1所示,React在DOM上封装 ...
- Django之模型层(单表操作)
一.ORM简介 MVC和MTV框架中包含一个重要部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库. ORM是‘对象-关系- ...
- Python 练习:使用 # 号输出长方形
使用 # 号输出一个长方形,用户可以指定宽和高 height = int(input("please input height: "))width = int(input(&quo ...
- Python 操作文件
open() 函数 模式 说明 r 只读模式 w 只写模式,文件不存在自动创建:存在则清空再写 a 只追加写,在文件最后追加写 r+ 打开一个文件用于读写.文件指针将会放在文件的开头. w+ 打开一个 ...
- 洛谷P2178 [NOI2015]品酒大会(后缀自动机 线段树)
题意 题目链接 Sol 说一个后缀自动机+线段树的无脑做法 首先建出SAM,然后对parent树进行dp,维护最大次大值,最小次小值 显然一个串能更新答案的区间是\([len_{fa_{x}} + 1 ...
- 【读书笔记】iOS-自定义URL Scheme注意事项
如果两个不同的应用注册了同样的URL Scheme,那么后安装的应用会响应符合这种协议格式的URL. 如果你的应用的iPhone和iPad版是各自独立的(即不是Universal类型的),那么你就不应 ...
- struts2文件上传大小限制问题小结(引用)
最后解决办法: 页面js控制上传文件的大小,在页面进行控制.如下代码 inputs是所有文本上传input DOM //名称信息 var nameStr=''; //大小信息 var sizeStr= ...
- WebLogic 8的安装与配置详谈
本文主要是以windouw下32位的版本为例展开介绍,主要包括其安装与配置. 一.图形界面安装过程 1.双击安装程序server815_win32.exe,开始进行程序的安装. 2.点击Next按钮进 ...