「NOIP2017」列队
传送门
Luogu
解题思路
一眼平衡树,应该没问题吧?
但我们一定要反应过来,单点的维护是非常之困难的,因为这是一个网格图而不仅仅是一条序列。
我们要考虑把修改操作全都放在序列上进行。
其实题面里是给了提示的,找一找在哪里。
于是我们可以考虑维护一些区间:
对于每一行,将前 \(m-1\) 个数的区间作为一个节点;将最后一列的 \(n\) 个数的的区间作为一个节点。
但是我们会遇到这样一个问题:当前的区间需要被切开,也就是要把一个节点分裂成两个节点。
其实这个和普通的序列操作是没什么区别的,具体实现看看代码就很显然了。
细节注意事项
- 节点空间开两倍
- 开
long long
参考代码
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cctype>
#include <cmath>
#include <ctime>
#define rg register
using namespace std;
template < class T > inline void read(T& s) {
s = 0; int f = 0; char c = getchar();
while (!isdigit(c)) f |= c == '-', c = getchar();
while (isdigit(c)) s = s * 10 + c - 48, c = getchar();
s = f ? -s : s;
}
typedef long long LL;
const int _ = 3000002 * 2;
int n, m, q, rt[_];
int tot, siz[_], pri[_], lc[_], rc[_];
LL r[_], l[_];
inline int newnode(LL L, LL R)
{ return siz[++tot] = R - L + 1, r[tot] = R, l[tot] = L, pri[tot] = rand(), tot; }
inline void pushup(int p) { siz[p] = siz[lc[p]] + siz[rc[p]] + r[p] - l[p] + 1; }
inline int merge(int x, int y) {
if (!x || !y) return x + y;
if (pri[x] > pri[y])
return rc[x] = merge(rc[x], y), pushup(x), x;
else
return lc[y] = merge(x, lc[y]), pushup(y), y;
}
inline void _split(int p, int k) {
if (k >= r[p] - l[p] + 1) return ;
LL pos = l[p] + k - 1;
int New = newnode(pos + 1, r[p]);
return r[p] = pos, rc[p] = merge(New, rc[p]), pushup(p);
}
inline void split(int p, int k, int& x, int& y) {
if (!p) { x = y = 0; return ; }
if (siz[lc[p]] >= k)
return y = p, split(lc[p], k, x, lc[y]), pushup(p);
else { _split(p, k - siz[lc[p]]);
return x = p, split(rc[p], k - siz[lc[p]] - (r[p] - l[p] + 1), rc[x], y), pushup(p);
}
}
int main() {
#ifndef ONLINE_JUDGE
freopen("in.in", "r", stdin);
freopen("out.out", "w", stdout);
#endif
srand(time(0));
read(n), read(m), read(q);
for (rg int i = 1; i <= n; ++i)
rt[i] = newnode((LL) (i - 1) * m + 1, (LL) i * m - 1);
for (rg int i = 1; i <= n; ++i)
rt[n + 1] = merge(rt[n + 1], newnode((LL) i * m, (LL) i * m));
for (rg int x, y; q--; ) {
read(x), read(y);
if (y == m) {
int a, b, c;
split(rt[n + 1], x, a, c);
split(a, x - 1, a, b);
printf("%lld\n", l[b]);
rt[n + 1] = merge(a, merge(c, b));
} else {
int a, b, c, aa, bb, cc;
split(rt[x], y, a, c);
split(a, y - 1, a, b);
printf("%lld\n", l[b]);
split(rt[n + 1], x, aa, cc);
split(aa, x - 1, aa, bb);
rt[x] = merge(a, merge(c, bb));
rt[n + 1] = merge(aa, merge(cc, b));
}
}
return 0;
}
完结撒花 \(qwq\)
「NOIP2017」列队的更多相关文章
- 2018.11.01 loj#2319. 「NOIP2017」列队(线段树)
传送门 唉突然回忆起去年去noipnoipnoip提高组试水然后省二滚粗的悲惨经历... 往事不堪回首. 所以说考场上真的有debuffdebuffdebuff啊!!!虽然当时我也不会权值线段树 这道 ...
- LOJ2319. 「NOIP2017」列队【线段树】
LINK 思路 神仙线段树 你考虑怎么样才能快速维护出答案 首先看看一条链怎么做? 首先很显然的思路是维护每个节点的是否出过队 然后对于重新入队的点 直接在后面暴力vector存一下就可以了 最核心的 ...
- 「NOIP2017」宝藏
「NOIP2017」宝藏 题解 博客阅读效果更佳 又到了一年一度NOIPCSP-S 赛前复习做真题的时间 于是就遇上了这道题 首先观察数据范围 \(1 \le n \le 12\) ,那么极大可能性是 ...
- 逛公园「NOIP2017」最短路+DP
大家好我叫蒟蒻,这是我的第一篇信竞题解blog [题目描述] 策策同学特别喜欢逛公园. 公园可以看成一张 \(N\) 个点 \(M\) 条边构成的有向图,且没有自环和重边.其中 \(1\) 号点是公园 ...
- BZOJ5319/LOJ2551「JSOI2018」列队
问题描述 作为一名大学生,九条可怜在去年参加了她人生中的最后一次军训. 军训中的一个重要项目是练习列队,为了训练学生,教官给每一个学生分配了一个休息位置.每次训练开始前,所有学生都在各自的休息位置休息 ...
- LOJ 2551 「JSOI2018」列队——主席树+二分
题目:https://loj.ac/problem/2551 答案是排序后依次走到 K ~ K+r-l . 想维护一个区间排序后的结果,使得可以在上面二分.求和:二分可以知道贡献是正还是负. 于是想用 ...
- 【LOJ】#2551. 「JSOI2018」列队
题解 老年选手一道裸的主席树都要看好久才看出来 首先熟练的把这个区间建成\(n\)个主席树 然后对于一个询问,我们相当于在主席树上二分一个mid,使得\(mid - K + 1\)正好和\([l,r] ...
- LOJ2316. 「NOIP2017」逛公园【DP】【最短路】【思维】
LINK 思路 因为我想到的根本不是网上的普遍做法 所以常数出奇的大,而且做法极其暴力 可以形容是带优化的大模拟 进入正题: 首先一个很显然的思路是如果在合法的路径网络里面存在零环是有无数组解的 然后 ...
- 「NOIP2017」「LuoguP3952」 时间复杂度(模拟,栈
题目描述 小明正在学习一种新的编程语言 A++,刚学会循环语句的他激动地写了好多程序并 给出了他自己算出的时间复杂度,可他的编程老师实在不想一个一个检查小明的程序, 于是你的机会来啦!下面请你编写程序 ...
随机推荐
- es 分词器介绍
按照单词切分,不做处理 GET _analyze { "analyzer": "standard", "text": "2 run ...
- 获取天气预报java代码
import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.IOException; imp ...
- Cisco AP-Sniffer模式空口抓包
第一步:WLC/AP侧 配置AP为sniffer模式: 配置提交后,AP会重启,并且将不能发出SSID为clients提供服务. 第二步:一旦AP重新加入WLC,配置AP抓取的信道和抓取后的数据包发 ...
- VSCODE 教程网
http://geek-docs.com/vscode/vscode-tutorials/vs-code-text-selection.html
- 在Eclipse或Myeclipse安装Maven插件的几种方法
http://blog.csdn.net/lfsfxy9/article/details/9397937
- lc 0228
目录 ✅ 412. Fizz Buzz 描述 解答 c数字转字符: other's c my c tdo py ✅ 235. 二叉搜索树的最近公共祖先 描述 解答 评价者 思路: c py ✅ 412 ...
- lc 0226
目录 ✅ 232. 用栈实现队列 描述 解答 c py ✅ 496. 下一个更大元素 I 描述 解答 java another java ✅ 232. 用栈实现队列 https://leetcode- ...
- @ResponseBody是如何起作用的
前言 最近参与的项目中,接口中返回的日期格式不对,发现项目中配置了fastjson作为spring的数据转换器,于是使用了fastjson的字段格式化转换注解 发现不起作用.这让我很疑惑,然后在fas ...
- Linux服务器yum安装mysql
阿里云Linux 服务器安装mysql 可以用rpm 和yum 方式安装,我这次安装是采用yum方式安装 请直接复制以下链接,看安装步骤 https://www.cnblogs.com/nzplear ...
- JMS消息传递的类型
对于消息的传递有两种类型: 一种是点对点的,即一个生产者和一个消费者一一对应: 另一种是发布/ 订阅模式,即一个生产者产生消息并进行发送后,可以由多个消费者进 行接收.