题目链接

题目描述

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

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

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

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

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

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

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

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

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

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

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

输入输出格式

输入格式:

输入共 q+1q+1 行。

第 1 行包含 3 个用空格分隔的正整数 n,m,qn,m,q,表示方阵大小是 nn 行 mm 列,一共发 生了 qq 次事件。

接下来 qq 行按照事件发生顺序描述了 qq 件事件。每一行是两个整数 x,yx,y,用一个空 格分隔,表示这个离队事件中离队的学生当时排在第 xx 行第 yy 列。

输出格式:

按照事件输入的顺序,每一个事件输出一行一个整数,表示这个离队事件中离队学 生的编号。

刚拿到这道题的时候,的确是无从下手的感觉,知道有这样的一道题,【SCOI2006】的动态最值,这样一道题,但是那道题是维护再一维空间上的删除并且挪动这样的一个操作,我们对于那道题只需要开线段树去维护(甚至不需要可持久化维护),维护的是size,也就是这段区间上有几个数,然后我们直接维护对应的最小值和最大值即可,线段树区间的长度就是原来的N个数的长度(因为只有N个数的说,并且还是只有删除操作)。然后一开始的时候,我们直接buildtree,并且直接赋值即可,然后在后面的找区间的时候,左区间超过L个数、右区间共有R个数,这样的(用size来维护)。

这里讲一下该怎么去维护:

我们假设左子树有X个节点,向右区间查找的时候,记得减去X,

如果ql<=X && qr>X,那么我们左右都要查;

如果ql>X && qr>X,那么我们直接查右区间;

如果ql<=X && qr<=X,我们只查左区间。

同样的,我们也可以删除。

讲了这么多与这道题没有关系的,接下来回归到正题上来。

思路:上面讲了这些,是为了开拓在可持久化线段树上的思路的,并且用到这道题就可以了。关键在于是怎么用?这道题会有这样的两种操作,一种是我们拎出来的人在第M列,那么他就不需要(操作1)向左移动了,直接向前移动即可;另一种是他不在第M列,此时我们就要考虑他要先向左移动,然后在向前对齐(向前对齐的时候,是不是就是可以看成我们挪动的是第M列的数)。

有了这些思路之后,就可以开始写了,因为这里的区间长度会比较的大,很显然,我们不能去用线段树来直接维护,那么就是需要用到可持久化线段树了,先想个办法维护一下在第M列时候的情况,因为这时候我们只需要向前看齐就可以了,那么我们是不是可以看成单链的一维空间那样子的想法(就是上面的思想了),但是这里需要补,怎么补就是个问题了,我们在这里可以开一个vector<>来存,把每个最后的值就是直接pushback就可以了。

那么,假如我们拎出去的人不是第M列的怎么办呢?假如拎出去的人的坐标是(x, y),那么我们是不是要去x这一行去找到y位的这个数,然后得到他的实际值,这时候(x, y)这个点空出来了,先要这一列的其他人都靠过来,然后再是第M列的人往前走,靠过来的做法与之前一维的时候相同,但是第M列的人向前走呢,我们可以看到M列的人,从第x位开始空出来,后面的人向前走,是不是就可以相当是第x位以后的点都向前移了一位,而查第M列的第x位不就是查其后面的数呢,然后这时候,就要把原来(x, y)上的值给赋值到M列的最后一个,也就是pushback()进去即可,同时还要把在M列x行后面的x+1行的值给塞到第x行的pushback后面去。

 #include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#define lowbit(x) ( x&(-x) )
#define pi 3.141592653589793
#define e 2.718281828459045
#define INF 0x3f3f3f3f
#define HalF (l + r)>>1
#define lsn rt<<1
#define rsn rt<<1|1
#define Lson lsn, l, mid
#define Rson rsn, mid+1, r
#define QL Lson, ql, qr
#define QR Rson, ql, qr
#define myself rt, l, r
namespace fastIO {
#define BUF_SIZE 100000
//fread -> read
bool IOerror = ;
inline char nc() {
static char buf[BUF_SIZE], *p1 = buf + BUF_SIZE, *pend = buf + BUF_SIZE;
if(p1 == pend) {
p1 = buf;
pend = buf + fread(buf, , BUF_SIZE, stdin);
if(pend == p1) {
IOerror = ;
return -;
}
}
return *p1++;
}
inline bool blank(char ch) {
return ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t';
}
inline void read(int &x) {
char ch;
while(blank(ch = nc()));
if(IOerror) return;
for(x = ch - ''; (ch = nc()) >= '' && ch <= ''; x = x * + ch - '');
}
#undef BUF_SIZE
};
using namespace fastIO;
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int maxN = 6e5 + ;
int N, M, Q, root[maxN], _UP, lc[ * maxN], rc[ * maxN], siz[ * maxN], tot;
vector<ll> vt[maxN];
inline void insert(int &rt, int l, int r, int k)
{
if(!rt) rt = ++tot;
siz[rt]++;
if(l == r) return;
int mid = HalF;
if(k <= mid) insert(lc[rt], l, mid, k);
else insert(rc[rt], mid + , r, k);
}
int query(int rt, int l, int r, int k)
{
if(l == r) return l;
int mid = HalF, size_L = mid - l + - siz[lc[rt]];
if(k <= size_L) return query(lc[rt], l, mid, k);
else return query(rc[rt], mid + , r, k - size_L);
}
inline ll del_M_las(int x, ll val) //如果这个人是最后那一排的话,就不需要向左看齐了
{
int pos = query(root[N + ], , _UP, x); insert(root[N + ], , _UP, pos);
ll ans = pos <= N ? (ll)pos * (ll)M : vt[N + ][pos - N - ];
vt[N + ].push_back(val ? val : ans);
return ans;
}
inline ll del_N(int x, int y)
{
int pos = query(root[x], , _UP, y); insert(root[x], , _UP, pos);
ll ans = pos < M ? (ll)(x - ) * (ll)M + pos : vt[x][pos - M];
vt[x].push_back(del_M_las(x, ans));
return ans;
}
int main()
{
tot = ;
scanf("%d%d%d", &N, &M, &Q);
//read(N); read(M); read(Q);
_UP = max(N, M) + Q;
int x, y;
while(Q--)
{
scanf("%d%d", &x, &y);
//read(x); read(y);
if(y == M) printf("%lld\n", del_M_las(x, ));
else printf("%lld\n", del_N(x, y));
}
return ;
}

【NOIP2017】列队【可持久化线段树】的更多相关文章

  1. Luogu3960 NOIP2017列队(splay/线段树)

    令splay中的一个点表示一段区间,需要使用其中某个点时将区间分裂即可,剩下的都是splay的基本操作了.写的非常丑陋,注意细节.感觉考场上肯定只能靠部分分苟活了.想起来去年因为各种莫名其妙的原因50 ...

  2. 洛谷P3994 Highway(树形DP+斜率优化+可持久化线段树/二分)

    有点类似NOI2014购票 首先有方程$f(i)=min\{f(j)+(dep_i-dep_j)*p_i+q_i\}$ 这个显然是可以斜率优化的... $\frac {f(j)-f(k)}{dep_j ...

  3. PYOJ 44. 【HNSDFZ2016 #6】可持久化线段树

    #44. [HNSDFZ2016 #6]可持久化线段树 统计 描述 提交 自定义测试 题目描述 现有一序列 AA.您需要写一棵可持久化线段树,以实现如下操作: A v p x:对于版本v的序列,给 A ...

  4. 【BZOJ-3673&3674】可持久化并查集 可持久化线段树 + 并查集

    3673: 可持久化并查集 by zky Time Limit: 5 Sec  Memory Limit: 128 MBSubmit: 1878  Solved: 846[Submit][Status ...

  5. 【BZOJ-2653】middle 可持久化线段树 + 二分

    2653: middle Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 1298  Solved: 734[Submit][Status][Discu ...

  6. HDU 4866 Shooting(持久化线段树)

    view code//第二道持久化线段树,照着别人的代码慢慢敲,还是有点不理解 #include <iostream> #include <cstdio> #include & ...

  7. 【BZOJ-3653】谈笑风生 DFS序 + 可持久化线段树

    3653: 谈笑风生 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 628  Solved: 245[Submit][Status][Discuss] ...

  8. 【BZOJ3673】&&【BZOJ3674】: 可持久化并查集 by zky 可持久化线段树

    没什么好说的. 可持久化线段树,叶子节点存放父亲信息,注意可以规定编号小的为父亲. Q:不是很清楚空间开多大,每次询问父亲操作后修改的节点个数是不确定的.. #include<bits/stdc ...

  9. 【BZOJ3207】花神的嘲讽计划I 可持久化线段树/莫队

    看到题目就可以想到hash 然后很自然的联想到可持久化权值线段树 WA:base取了偶数 这道题还可以用莫队做,比线段树快一些 可持久化线段树: #include<bits/stdc++.h&g ...

随机推荐

  1. osi七层协议 Open System Interconnection

    一, 操作系统基础 操作系统:(Operating System,简称OS)是管理和控制计算机硬件与软件资源的计算机程序,是直接运行在"裸机"上的最基本的系统软件,任何其他软件都必 ...

  2. css中的居中的方法

    一.垂直居中 (1)inline或者inline-*元素 1. 单行文字 设置上下padding相等 以前一直以为inline元素是没有上下的padding和margin的,其实不然,他们是有上下的p ...

  3. jQuery淡入淡出瀑布流效果

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  4. R语言基础篇——数据对象

    1.基本数据类型(numeric,logical,character,NA,double,complex,integer) 2.日期变量 常用函数 Sys.Date()-返回系统当前的日期,Sys.t ...

  5. Nginx针对前端静态资源的缓存处理

    当用户上报一个线上的bug后,开发者修改前端代码的bug上新后,用户反映问题依旧存在的问题...这种情况是不是曾经遇到过,这个问题跟浏览器的缓存机制有很大关系(强制缓存和协商缓存,这里我就不介绍具体的 ...

  6. CentOS 7 FTP的安装与配置

    CentOS7 FTP安装与配置 1.FTP的安装 #安装yum install -y vsftpd #设置开机启动systemctl enable vsftpd.service #启动systemc ...

  7. 理解Promise (1)

    new Promise 需要传递一个执行器 (函数) 函数有两个参数 resolve reject promise 承诺 默认的状态是pengding 调用 resolve 表示成功 reject 表 ...

  8. 19.go语言基础学习(下)——2019年12月16日

    2019年12月16日16:57:04 5.接口 2019年11月01日15:56:09 5.1 duck typing 1. 2. 接口 3.介绍 Go 语言的接口设计是非侵入式的,接口编写者无须知 ...

  9. Spring MVC (二)

    一.使用 @RequestMapping 映射请求 Spring MVC使用@RequestMapping注解为控制器指定可以处理哪些URL请求 在控制器的类定义以及方法定义处都可以标注 类定义处:提 ...

  10. 1349 - View's SELECT contains a subquery in the FROM clause

    mysql创建视图 报错1349 - View's SELECT contains a subquery in the FROM clause:: 原因创建视图的sql语句中有不支持子查询, 所以需要 ...