Description

Sylvia 是一个热爱学习的女♂孩子。

前段时间,Sylvia 参加了学校的军训。众所周知,军训的时候需要站方阵。

Sylvia 所在的方阵中有n×m名学生,方阵的行数为 n,列数为 m。

为了便于管理,教官在训练开始时,按照从前到后,从左到右的顺序给方阵中 的学生从 1 到 n×m 编上了号码(参见后面的样例)。即:初始时,第 iii 行第 jjj 列 的学生的编号是(i−1)×m+j。

然而在练习方阵的时候,经常会有学生因为各种各样的事情需要离队。在一天 中,一共发生了 q 件这样的离队事件。每一次离队事件可以用数对(x,y)(1≤x≤n,1≤y≤m)描述,表示第 x 行第 y 列的学生离队。

在有学生离队后,队伍中出现了一个空位。为了队伍的整齐,教官会依次下达 这样的两条指令:

  1. 向左看齐。这时第一列保持不动,所有学生向左填补空缺。不难发现在这条 指令之后,空位在第 x 行第 m 列。
  2. 向前看齐。这时第一行保持不动,所有学生向前填补空缺。不难发现在这条 指令之后,空位在第 n 行第 m 列。

    教官规定不能有两个或更多学生同时离队。即在前一个离队的学生归队之后, 下一个学生才能离队。因此在每一个离队的学生要归队时,队伍中有且仅有第 n 行 第 m 列一个空位,这时这个学生会自然地填补到这个位置。

    因为站方阵真的很无聊,所以 Sylvia 想要计算每一次离队事件中,离队的同学 的编号是多少。

    注意:每一个同学的编号不会随着离队事件的发生而改变,在发生离队事件后 方阵中同学的编号可能是乱序的。

solution

正解:线段树/树状数组/平衡树

\(30\%\):开个 \(n*m\) 的数组模拟即可

\(50\%\):发现只有500行有改动,所以单独拿出这500行和最后一列,模拟即可.

\(80\%\):只有一行的话,我们就开一个 \(m+q\) 的数组,然后树状数组维护每一个位置是否有人,并且维护每一个位置的人的id,这样就会产生很多空位,询问就是查找第 \(y\) 个有人的位置的id,二分+树状数组 或 直接线段树查找第k大即可,与 \(70\) 分不同的是,还需要再维护最后一列,像行一样维护即可

\(100\%\):和 \(80\) 分类似,想到有很多位置根本没有大的变动,我们像之前一样,我们把只需要出队的位置删除即可,所以我们维护每一个位置是否被删,但是不太好存,所以用动态开点线段树标记删除位置,然后像之前一样二分找出第 \(y\) 个有人的位置即可,还有一个不同的是,id数组需要动态维护,所以开个vector存即可,所以100和80的区别仅在于是否使用动态内存.

前50%和另外 20%

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#define RG register
using namespace std;
typedef long long ll;
const int N=50005,M=300005;
int n,m,Q,b[M],num=0,tot;
struct node{int x,y;}e[M]; namespace brute{
ll a[505][N],line[N],r[N];
void main(){
for(int i=1;i<=tot;i++)
for(int j=1;j<=m;j++)
a[i][j]=(ll)(b[i]-1)*m+j;
for(int i=1;i<=n;i++)
line[i]=(ll)(i-1)*m+m;
for(int P=1;P<=Q;P++){
int x=e[P].x,y=e[P].y,hxy;
printf("%lld\n",a[x][y]);
hxy=a[x][y];
for(int i=y;i<m;i++)r[i]=a[x][i+1];
for(int i=y;i<m;i++)a[x][i]=r[i];
for(int i=b[x];i<n;i++)r[i]=line[i+1];
for(int i=b[x];i<n;i++)line[i]=r[i];
line[n]=hxy;
for(int i=1;i<=tot;i++)
a[i][m]=line[b[i]];
}
}
} namespace cheat{
int id[M*2],tr[M*2];
void add(int sta,int ad){
for(int i=sta;i<=m+Q;i+=(i&(-i)))tr[i]+=ad;
}
int qry(int sta){
int ret=0;
for(int i=sta;i>=1;i-=(i&(-i)))ret+=tr[i];
return ret;
}
int midit(int k){
int l=1,r=m+Q,mid,tmp,ret=0;
while(l<=r){
mid=(l+r)>>1;
tmp=qry(mid);
if(tmp>=k)ret=mid,r=mid-1;
else l=mid+1;
}
return ret;
}
void main(){
for(int i=1;i<=m;i++)
add(i,1),id[i]=i; int cnt=m;
for(int P=1;P<=Q;P++){
int y=e[P].y;
int p=midit(y);
printf("%d\n",id[p]);
cnt++;
add(p,-1);add(cnt,1);
id[cnt]=id[p];
}
}
} void work(){
scanf("%d%d%d",&n,&m,&Q);
for(int i=1;i<=Q;i++){
scanf("%d%d",&e[i].x,&e[i].y);
b[++num]=e[i].x;
}
sort(b+1,b+num+1);
tot=unique(b+1,b+num+1)-b-1;
for(int i=1;i<=n;i++)
e[i].x=lower_bound(b+1,b+tot+1,e[i].x)-b;
if(Q<=500)brute::main();
else{
if(n==1)cheat::main();
else brute::main();
}
} int main(){
work();
return 0;
}

100分

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#define RG register
#define il inline
#define iter iterator
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
using namespace std;
typedef long long ll;
const int N=300005,M=6000100;
vector<ll>S[N];
int n,m,Q,tot,root[N],ls[M],rs[M],v[M],cnt=0; inline void Modify(int &rt,int l,int r,int sa){
if(!rt)rt=++cnt;
v[rt]++;
if(l==r)return ;
int mid=(l+r)>>1;
if(sa<=mid)Modify(ls[rt],l,mid,sa);
else Modify(rs[rt],mid+1,r,sa);
} inline int qry(int rt,int l,int r,int k){
if(l==r)return l;
int mid=(l+r)>>1;
int sum=mid-l+1-v[ls[rt]];
if(k<=sum)return qry(ls[rt],l,mid,k);
return qry(rs[rt],mid+1,r,k-sum);
} inline ll caline(int x){
int r=qry(root[n+1],1,tot,x);
Modify(root[n+1],1,tot,r);
return r<=n?1ll*(r-1)*m+m:S[n+1][r-n-1];
}
inline ll calrow(int x,int y){
int r=qry(root[x],1,tot,y);
Modify(root[x],1,tot,r);
return r<m?1ll*(x-1)*m+r:S[x][r-m];
} void work()
{
int x,y;
ll ret,tmp;
scanf("%d%d%d",&n,&m,&Q);
tot=Max(n,m)+Q;
while(Q--){
scanf("%d%d",&x,&y);
if(y==m){
ret=caline(x);
S[n+1].push_back(ret);
printf("%lld\n",ret);
}
else{
ret=calrow(x,y);
printf("%lld\n",ret);
S[n+1].push_back(ret);
tmp=caline(x);
S[x].push_back(tmp);
}
}
} int main()
{
freopen("pp.in","r",stdin);
freopen("pp.out","w",stdout);
work();
return 0;
}

【NOIP 2017】列队的更多相关文章

  1. NOIP 2017 列队 - Splay - 树状数组

    题目传送门 传送点I 传送点II 题目大意 (家喻户晓的题目应该不需要大意) (我之前咋把NOIP 2017打成了NOIP 2018,好绝望) Solution 1 Splay 每行一颗Splay,没 ...

  2. [NOIp 2017]列队

    Description Sylvia 是一个热爱学习的女孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Sylvia 所在的方阵中有$n \times m$名学生, ...

  3. [NOIP]2017列队——旋转treap/非旋转treap

    Sylvia 是一个热爱学习的女孩子.  前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Sylvia所在的方阵中有n × m名学生,方阵的行数为 n,列数为m.  为了便 ...

  4. 洛谷 P3960 [ NOIP 2017 ] 列队 —— 线段树

    题目:https://www.luogu.org/problemnew/show/P3960 NOIP 题,不用很复杂的数据结构...但又参考了许多: 要求支持维护删除第 k 个和在末尾插入的数据结构 ...

  5. 「NOIP 2017」列队

    题目大意:给定一个 $n times m$ 的方阵,初始时第 $i$ 行第 $j$ 列的人的编号为 $(i-1) times m + j$,$q$ 次给出 $x,y$,让第 $x$ 行 $y$ 列的人 ...

  6. NOIP 2017 解题报告

    ---恢复内容开始--- NOIP 2017 的题真的很难啊,怪不得当年我这个萌新爆零了(当然现在也是萌新)越学越觉得自己什么都不会. 想要成为强者要把这些好题都弄懂弄透 至少现在6道题我都比较陌生 ...

  7. 【游记】NOIP 2017

    时间:2017.11.11~2017.11.12 地点:广东省广州市第六中学 Day1 T1:看到题目,心想这种题目也能放在T1? 这个结论我之前遇到过至少3次,自己也简单证明过.初见是NOIP200 ...

  8. NOIP 2017 小凯的疑惑

    # NOIP 2017 小凯的疑惑 思路 a,b 互质 求最大不能表示出来的数k 则k与 a,b 互质 这里有一个结论:(网上有证明)不过我是打表找的规律 若 x,y(设x<y) 互质 则 : ...

  9. 历年真题 未完成(Noip 2008 - Noip 2017)

    Noip 2008 :全部 Noip 2009 :全部 Noip 2010 :AK Noip 2011 :AK Noip 2012 : Vigenère 密码,国王游戏,开车旅行 Noip 2013 ...

  10. 洛谷 P3951 NOIP 2017 小凯的疑惑

    洛谷 P3951 NOIP 2017 小凯的疑惑 题目描述 小凯手中有两种面值的金币,两种面值均为正整数且彼此互素.每种金币小凯都有 无数个.在不找零的情况下,仅凭这两种金币,有些物品他是无法准确支付 ...

随机推荐

  1. 201621123044 《Java程序设计》第六周实验总结

    1. 本周学习总结 1.1 面向对象学习暂告一段落,请使用思维导图,以封装.继承.多态为核心概念画一张思维导图或相关笔记,对面向对象思想进行一个总结. 注1:关键词与内容不求多,但概念之间的联系要清晰 ...

  2. IOS webview iframe 宽度超出屏幕解决方案

    IOS 真机webview中,iframe 却不能很好地适应屏幕大小,总是超出屏幕尺寸,需要左右滚动才能看到完整页面. <div style="overflow: auto;-webk ...

  3. 搭建java环境——使用Sublime Text 3(windows环境)

    实现sublime Text 3对Java编译执行 参考网址:http://tieba.baidu.com/p/2609515186 1.1直接在安装路径下找到*\Packages\Java.subl ...

  4. PostgreSQL 客户端乱码问题

    关于客户端和服务器端的乱码问题, POSTGRESQL字符集问题总结 总结的很详细, 特别棒. 这里让我头痛了很久的问题在于 终端 上字符编码的问题, 由于我的mbp上的 iterm2 的默认编码为 ...

  5. 在wamp集成环境下安装laravel5.2.*框架

    虽然官方一直强烈推荐使用homestead,但是这个相对麻烦一点,所以我还是选择使用wamp集成开发环境.还有这里我只讲解windows系统下的安装,其他例如mac或linux就不写了,此文章是面向刚 ...

  6. 织梦dedecms默认网站地图sitemap.html优化

    网站地图对于网站优化很重要,搜索引擎就是靠网站地图去收录网站页面,本文主要讲解优化织梦自带的网站地图功能.     织梦自带的网站地图使用方法:织梦后台--生成--HTML更新--更新网站地图,可以在 ...

  7. NFC驱动调试

    1.NFC基本概念: NFC 又称为近场通信,是一种新兴技术,可以在彼此靠近的情况下进行数据交换,是由非接触式射频识别(RFID) 及互连互通技术整合演变而来,通过单一芯片集成感应式读卡器: NFC有 ...

  8. 儿童节,我们从零开始——Python入门资源推荐

    原创 2017-06-01 玄魂工作室 玄魂工作室 今天是六一儿童节,首先祝所有的小朋友身体健康,能永远生活在一个没有战争,没有压迫的世界里,永远快乐. 上一篇文章,很多人都对Python的各种书籍感 ...

  9. Web Api 返回图片流

    public class TestController : ApiController { public HttpResponseMessage GetImg() { //获取文件的绝对路径 stri ...

  10. 由路由器AP隔离引起的WEB服务不能访问的问题

    最近在自己的电脑上运行了一个Web服务,发现它只能被本机访问,无法在同一个局域网的其它设备访问. 于是在网上搜索了各种资料,通通都是在操作系统层面来分析解决问题的. 而我怎么尝试都不成功的情况下,差点 ...