【NOIP 2017】列队

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;
}

转载于:https://www.cnblogs.com/Yuzao/p/7920813.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/415196.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AAPT2 error: check logs for details.

/1、全部替代你的项目build.gradle内容&#xff1a; // Top-level build file where you can add configuration options common to all sub-projects/modules.buildscript {repositories { // maven { // url https://maven.google.com // }mavenCe…

工作175:数据在表格横坐标动态显示

1数据格式 2对数据进行处理 created() {getAction("/task/arrange").then(res>{console.log(res)this.tableDatares.data.itemsthis.timeres.data.timeconsole.log(this.time)res.data.time.map((value,index)>{console.log(value)let arr {prop:,label:value.…

mac安装mysql记录,使用zsh

1、正常安装去官网下载最新版&#xff0c;依次下一步就可以。 2、配置zsh 执行vim ~/.zshrc_profil 添加mysql/bin的目录&#xff1a; export PATH$PATH:/usr/local/mysql/bin添加完成后:wq保存 最后在命令行输入source ~/.zshrc_profile&#xff0c;执行脚本。 3、连接数…

vue中的ES6语法整理1

1、箭头函数 ES6允许使用“箭头”&#xff08;>&#xff09;定义函数 var f v > v;//等价于var f function(v){return v; }; 如果箭头函数不需要参数&#xff0c;则定义如下&#xff1a; var f () > 5; // 等同于 var f function () { return 5 }; 如果箭头函…

Android 生成二维码,条形码,二维码添加logo

zxing生成二维码 implementation com.google.zxing:core:3.3.1 implementation(name: zxing-1.0.1, ext: aar) implementation com.github.bumptech.glide:glide:4.9.0 annotationProcessor com.github.bumptech.glide:compiler:4.9.0 private Bitmap getCodeBitmap(String c…

java setDataSource 报红

开始学习spring security遇到一个问题&#xff0c;setDataSource老是报红 解决方案&#xff0c;在pom.xml中增加 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId><version>2…

Android 识别图片二维码,以及设置状态栏颜色

zxing依赖&#xff1a;compile cn.yipianfengye.android:zxing-library:2.2 初始化&#xff1a;private String SAVE_PIC_PATH Environment.getExternalStorageState().equalsIgnoreCase(Environment.MEDIA_MOUNTED)? Environment.getExternalStorageDirectory().getAbsolute…

linux之sed

sed 是一个流编辑器(stream editor)&#xff0c;主要用来执行文本替换。但 sed 的主要设计目的是以批处理的方式而不是交互的方式来编辑文件。 命令简介 基本命令格式 sed [常用选项] 命令文本 输入 常用选项 -n (--quiet, --silent)&#xff1a;安静模式。在 sed 的基本用法中…

mac 升级 15.4之后,部分软件无法打开解决

我的mac升级版本后&#xff0c;有一些好用的软件就打不开了&#xff0c;比如orc识别软件text scanner 解决方法&#xff1a; sudo codesign -f -s - --deep /Applications/TextScan.app可以直接输入 sudo codesign -f -s - --deep 再把文件拖拽过去即可

Android 截图,截取指定view截图

二、具体实现方式 实用截图方法截取整个activity public static Bitmap shotActivity(Activity ctx) {View view ctx.getWindow().getDecorView();view.setDrawingCacheEnabled(true);view.buildDrawingCache();Bitmap bp Bitmap.createBitmap(view.getDrawingCache(), 0, 0…

java使用AntPathMatcher进行uri匹配

需求&#xff1a;我在做rbac权限校验的时候&#xff0c;设置管理员的访问路径为/admin/**,希望所有的开头为/admin/的uri操作地址都能进行匹配判断。 import org.springframework.util.AntPathMatcher;String content "/admin/acuff"; String pattern "/admi…

百度经验 回享计划

https://jingyan.baidu.com/user/income 转载于:https://www.cnblogs.com/qdrs/p/7940353.html

Android 扫描二维码demo

demo下载链接&#xff1a;https://download.csdn.net/download/meixi_android/10779714 zxing依赖&#xff1a; compile cn.yipianfengye.android:zxing-library:2.2 扫描类&#xff1a; /*** 作者&#xff1a;created by meixi* 邮箱&#xff1a;13164716840163.com* 日期&…

neditor 自定义工具栏配置

neditor是ueditor的亚种。我已经实现了vueneditor的封装&#xff0c;下面记录一下常用工具栏的配置。 1、配置方法 实例化编辑器的时候传入 toolbars 参数 2、参数列表 名称描述anchor锚点undo撤销redo重做bold加粗indent首行缩进snapscreen截图italic斜体underline下划线st…

前端学习(2666):完成vue3.0的todolist编辑

1点击编辑 2编辑逻辑 3进入编辑状态

课后作业-团队编程项目总结

成员&#xff1a;王志昂&#xff08;组长&#xff09; 郑 月 李古宇 孙晨旭 鞠牧孜 程冠菲 项目名称&#xff1a;吃货之家 早在商朝末年&#xff0c;太公望(别名:姜太公&#xff0c;姜子牙)在营丘之战时所创制的太公望红焖鸡&#xff0c;在姜太公建立齐国后&#xff0c;红焖鸡(…