题解

本题的解法是丰富多彩的!

线段树做法是极好的

代码非常之少

一个很显然的想法是维护 \(n+1\) 颗线段树

那要怎么维护才能不爆空间呢?

我们发现尽管 \(n \times m\) 那么大

但 \(q\) 相比 \(n \times m\) 小得多

也就是说变动的点比较少

于是我们抓住这点

考虑只记录变动的点

行的线段树维护 \([1,m-1]\) 位置的信息

列的线段树维护 \([1,n]\) 的位置的信息

那我一颗线段树就记录那些点不在原来位置了

也就是说一颗线段树长为 \(\max(n,m)+q\) (为什么?待会再解释)

每一位只为 \(0\) 或 \(1\) 表示 没变或变了

\(1\) 表示变了是因为没变的太多无法记录,那就记变的吧

这样线段树动态开点空间就可以接受了

然后变动的点我们考虑它后来的位置

依题知它会到最后一列的末端,然后最后一列它所在的行的点会到它所在行的线段是的末端

我们无法向平衡树一样动态移动(插入,删除)点,但题目只需插入到末端

所以我们预留空间把插入的点放到末端,然后它原来位置标记为 \(1\),表示此处无点

对于查询,我们知道为第 \(x(x<=n)\) 颗线段树的 \(y\) 位置的点的编号为 \((x-1) \times m+y\)

但他不一定在原队列 \(y\) 位置

因为前面有些点为 \(1\) 空置,一个区间长度减去区间 \(1\) 的个数才是区间有的数

所以我们只要查询排名为 \(y\) 的位置的编号,记为 \(z\)

那么在询问中,当 \(z<m\) 时,它的编号为 \((x-1) \times m+z\)

当 \(z >= m\) 时说明前面有空位,有点移动到后面了

我们用 \(n+1\) 个 \(vector\) 储存每个线段树依次移动到后面的点,输出 \(S[x][z-m]\) 即可

列同理

\(Code\)

#include<cstdio>
#include<vector>
#include<iostream>
#define LL long long
using namespace std; const int N = 3e5 + 5, M = 6e6 + 5;
int n, m, q, sum[M], ls[M], rs[M], rt[N], Len, size;
vector<LL> S[N]; void update(int &p, int l, int r, int x)
{
if (!p) p = ++size;
++sum[p];
if (l == r) return;
int mid = (l + r) >> 1;
if (x <= mid) update(ls[p], l, mid, x);
else update(rs[p], mid + 1, r, x);
} int query(int p, int l, int r, int k)
{
if (l == r) return l;
int mid = (l + r) >> 1, s = mid - l + 1 - sum[ls[p]];
if (k <= s) return query(ls[p], l, mid, k);
return query(rs[p], mid + 1, r, k - s);
} inline LL move_forward(int x)
{
int p = query(rt[n + 1], 1, Len, x);
update(rt[n + 1], 1, Len, p);
return (p <= n ? (1LL * p * m) : (S[n + 1][p - n - 1]));
} inline LL move_left(int x, int y)
{
int p = query(rt[x], 1, Len, y);
update(rt[x], 1, Len, p);
return (p < m ? (1LL * (x - 1) * m + p) : (S[x][p - m]));
} int main()
{
freopen("phalanx.in", "r", stdin);
freopen("phalanx.out", "w", stdout);
scanf("%d%d%d", &n, &m, &q);
Len = max(n, m) + q;
for(int x, y; q; --q)
{
scanf("%d%d", &x, &y);
LL z;
if (y == m) z = move_forward(x), printf("%lld\n", z), S[n + 1].push_back(z);
else z = move_left(x, y), printf("%lld\n", z), S[n + 1].push_back(z),
z = move_forward(x), S[x].push_back(z);
}
}

【NOIP2017提高组正式赛】列队的更多相关文章

  1. [jzoj]5478.【NOIP2017提高组正式赛】列队

    Link https://jzoj.net/senior/#main/show/5478 Description Sylvia 是一个热爱学习的女孩子.       前段时间,Sylvia 参加了学校 ...

  2. 【NOIP2017 提高组正式赛】列队 题解

    题目大意 有一个 \(n\times m\) 的方阵,每次有 \((x,y)\) 离开,离开后有两个命令 向左看齐.这时第一列保持不动,所有学生向左填补空缺.这条指令之后,空位在第 \(x\) 行第 ...

  3. NOIP2017提高组 模拟赛15(总结)

    NOIP2017提高组 模拟赛15(总结) 第一题 讨厌整除的小明 [题目描述] 小明作为一个数学迷,总会出于数字的一些性质喜欢上某个数字,然而当他喜欢数字k的时候,却十分讨厌那些能够整除k而比k小的 ...

  4. NOIP2017提高组 模拟赛13(总结)

    NOIP2017提高组 模拟赛13(总结) 第一题 函数 [题目描述] [输入格式] 三个整数. 1≤t<10^9+7,2≤l≤r≤5*10^6 [输出格式] 一个整数. [输出样例] 2 2 ...

  5. NOIP2017提高组模拟赛 10 (总结)

    NOIP2017提高组模拟赛 10 (总结) 第一题 机密信息 FJ有个很奇怪的习惯,他把他所有的机密信息都存放在一个叫机密盘的磁盘分区里,然而这个机密盘中却没有一个文件,那他是怎么存放信息呢?聪明的 ...

  6. NOIP2017提高组模拟赛 8(总结)

    NOIP2017提高组模拟赛 8(总结) 第一题 路径 在二维坐标平面里有N个整数点,Bessie要访问这N个点.刚开始Bessie在点(0,0)处. 每一步,Bessie可以走到上.下.左.右四个点 ...

  7. NOIP2017提高组模拟赛 9 (总结)

    NOIP2017提高组模拟赛 9 (总结) 第一题 星星 天空中有N(1≤N≤400)颗星,每颗星有一个唯一的坐标(x,y),(1≤x,y ≤N).请计算可以覆盖至少K(1≤K≤N)颗星的矩形的最小面 ...

  8. NOIP2017提高组模拟赛 7(总结)

    NOIP2017提高组模拟赛 7(总结) 第一题 斯诺克 考虑这样一个斯诺克球台,它只有四个袋口,分别在四个角上(如下图所示).我们把所有桌子边界上的整数点作为击球点(除了4个袋口),在每个击球点我们 ...

  9. NOIP2017提高组模拟赛5 (总结)

    NOIP2017提高组模拟赛5 (总结) 第一题 最远 奶牛们想建立一个新的城市.它们想建立一条长度为N (1 <= N <= 1,000,000)的 主线大街,然后建立K条 (2 < ...

  10. NOIP2017提高组模拟赛4 (总结)

    NOIP2017提高组模拟赛4 (总结) 第一题 约数 设K是一个正整数,设X是K的约数,且X不等于1也不等于K. 加了X后,K的值就变大了,你可以重复上面的步骤.例如K= 4,我们可以用上面的规则产 ...

随机推荐

  1. 5V升压12.6V

    产品概述 PW4053 是一款 5V 输入,最大 1.2A 充电电流,支持三节锂离子电池的升压充电管理 IC.PW4053 集成功率 MOS,采用异步开关架构,使其在应用时仅需极少的外围器件,可有效减 ...

  2. Django中ORM多对多三种创建方式(全自动-纯手动-半自动)

    一:多对多三种创建方式 1.全自动: 利用orm自动帮我们创建第三张关系表 class Book(models.Model): name = models.CharField(max_length=3 ...

  3. Python中open()文件操作/OS目录操作

    File对象测试数据的读写与操作 #def open(file, mode='r', buffering=None, encoding=None, errors=None, newline=None, ...

  4. Jmeter之非GUI下执行脚本

    1.进入jmeter 应用所在路径 eg: cd D:\Program Files\apache-jmeter-5.2\bin 2.输入运行命令:jmeter -n -t [jmx脚本路径] -l [ ...

  5. 6、发送验证码功能(Redis)

    一.业务需求: 1.后端随机生成短信验证码,并在服务器端保存一定时间(redis): 2.将短信验证码发给用户: 3.用户输入短信验证码提交后,在后端与之前生成的短信验证码作比较,如果相同说明验证成功 ...

  6. CH32V307以太网(芯片内部10M)-针对新固件的Lib库

    沁恒的CH32V307网络库在前段时间做了一个更新,相对于以前的Lib,主要的功能没有什么特别大的变化,但是底层的一些操作仔细看的话,还是不少的区别的. 首先,官方提供的例程,工程结构以及头文件优一些 ...

  7. 更改json节点key

    json节点key更改,给朋友写的小tool,顺便记录一下 单个指定 每一个需要修改的key,都需要指定 /** * 需要转义的key对象 * 原key: 新key */ const jsonKeys ...

  8. 音频音量调整中的ramp up & down

    在日常生活中不管是打电话还是听音乐,都会遇到音量不合适而去调整音量的情况.如果音量调整软件处理不好,就会听到pop noise.产生pop noise的原因是音量直接从当前值骤变到目标值,而不是缓慢的 ...

  9. 均有商业公司支持!2023再看数据湖 hudi iceberg delta2 社区发展现状!

    开源数据湖三剑客 Apache hudi.Apache iceberg .Databricks delta 近年来大动作不断. 2021年8月,Apache Iceberg 的创始人 Ryan Blu ...

  10. 通过Sqoop来传输mysql/oracle/vertica数据至Hive

    1.环境: CDH SQOOP2 2.操作步骤 1.准备表与主键 表名:test.test_log 主键:sys_log_id 建表语句 CREATE TABLE hbase_test_test_lo ...