luoguP3690 列队
https://www.luogu.org/problemnew/show/P3960
作为一个初二蒟蒻要考提高组,先做一下17年的题目
我们发现进行一次操作相当于
- 把第 x 行的第 y 个弹出记为 a,其余向左移 = splay 中弹出第 y 个
- 把第 m 列的第 x 个弹出记为 b,其余向上移 = splay 中弹出第 x 个
- 把 b 插到第 x 行末尾 = splay 在队尾插入 b
- 把 a 插到第 m 列末尾 = splay 在队尾插入 a
然后对于没有用到的节点先合并着,要用就拆开
#include <bits/stdc++.h>
#define int long long
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
template <typename _T>
inline void read(_T &f) {
f = 0; _T fu = 1; char c = getchar();
while(c < '0' || c > '9') {if(c == '-') fu = -1; c = getchar();}
while(c >= '0' && c <= '9') {f = (f << 3) + (f << 1) + (c & 15); c = getchar();}
f *= fu;
}
const int N = 300000 + 10;
struct Node {
int l, r, size, id;
Node *ch[2];
Node (int a, int b, int c, int d, Node *e, Node *f) {
l = a, r = b, size = c, id = d;
ch[0] = e, ch[1] = f;
}
}*root[N], *null;
int w[N];
int n, m, q;
void update(Node *u) {
u -> size = u -> ch[0] -> size + u -> ch[1] -> size + u -> r - u -> l + 1;
}
void rotate(Node *&u, int d) {
Node *tmp = u -> ch[d];
u -> ch[d] = tmp -> ch[d ^ 1];
tmp -> ch[d ^ 1] = u;
update(u); update(tmp);
u = tmp;
}
void splay(Node *&u, int k) {
int ltree = u -> ch[0] -> size;
if(ltree < k && (ltree + (u -> r - u -> l + 1) >= k)) return;
int d = k > ltree;
int k2 = d ? k - ltree - (u -> r - u -> l + 1) : k;
int ltree2 = u -> ch[d] -> ch[0] -> size;
if(ltree2 >= k2 || (ltree2 + u -> ch[d] -> r - u -> ch[d] -> l + 1) < k2) {
int d2 = k2 > ltree2;
splay(u -> ch[d] -> ch[d2], d2 ? k2 - ltree2 - (u -> ch[d] -> r - u -> ch[d] -> l + 1) : k2);
if(d == d2) rotate(u, d2);
else rotate(u -> ch[d], d2);
}
rotate(u, d);
}
Node *build(int l, int r) {
if(l > r) return null;
if(l == r) return new Node(w[l], w[l], 1, w[l], null, null);
int mid = (l + r) >> 1;
return new Node(w[mid], w[mid], r - l + 1, w[mid], build(l, mid - 1), build(mid + 1, r));
}
void merge(Node *&a, Node *&b) {
if(a == null) a = b, b = null;
if(b == null) return;
splay(a, a -> size);
a -> ch[1] = b;
update(a);
}
int split(Node *&u, int k) {
splay(u, k);
int ltree = u -> ch[0] -> size;
int K = k - ltree, l = u -> l, r = u -> r;
if(K != 1) {
Node *tmp = new Node(l, l + K - 2, K - 1, l, u -> ch[0], null);
u -> ch[0] = tmp; u -> l = l + K - 1; update(u -> ch[0]);
}
if(K != r - l + 1) {
Node *tmp = new Node(l + K, r, r - l - K + 1, l + K, null, u -> ch[1]);
u -> ch[1] = tmp; u -> r = l + K - 1; update(u -> ch[1]);
}
Node *t2 = u -> ch[1]; u -> ch[1] = null; u -> id = u -> l;
int ans = u -> id; u = u -> ch[0]; merge(u, t2); return ans;
}
void ins(Node *&u, int x) {
if(u == null) u = new Node(x, x, 1, x, null, null);
else {
splay(u, u -> size);
u -> ch[1] = new Node(x, x, 1, x, null, null);
update(u);
}
}
signed main() {
null = new Node(0, -1, 0, 0, 0, 0);
read(n); read(m); read(q);
for(int i = 1; i <= n; i++) {
root[i] = new Node(1 + (i - 1) * m, m - 1 + (i - 1) * m, m - 1, 1 + (i - 1) * m, null, null);
}
for(int i = 1; i <= n; i++) w[i] = i * m;
root[0] = build(1, n);
for(int i = 1; i <= q; i++) {
int a, b;
read(a); read(b);
if(b == m) {
int ans = split(root[0], a);
printf("%lld\n", ans);
ins(root[0], ans);
continue;
}
int ans = split(root[a], b);
printf("%lld\n", ans);
int tmp = split(root[0], a);
ins(root[a], tmp);
ins(root[0], ans);
}
return 0;
}
luoguP3690 列队的更多相关文章
- 关于PHP堆栈与列队
在PHP中数组常被当作堆栈(后进先出:LIFO)与队列(先进先出:FIFO)结构来使用.PHP提供了一组函数可以用于push与pop(堆栈)还有shift与unshift(队列)来操作数组元素.堆栈与 ...
- 在PHP中如何使用消息列队
/** * 消息列队服务 * @author zhou.tingze * @example * -----------------------------------Create----------- ...
- BZOJ2720: [Violet 5]列队春游
2720: [Violet 5]列队春游 Time Limit: 5 Sec Memory Limit: 128 MBSubmit: 173 Solved: 125[Submit][Status] ...
- [NOIp 2017]列队
Description Sylvia 是一个热爱学习的女孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Sylvia 所在的方阵中有$n \times m$名学生, ...
- NOIP2017D2T3 列队—Treap
NOIP2017列队 Description Sylvia 是一个热爱学习的女孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Sylvia所在的方阵中有n × m ...
- P2649 - 【NOIP2017】列队
Description Sylvia 是一个热爱学习的女孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Sylvia 所在的方阵中有 n×m 名学生,方阵的行数为 ...
- WebForm应用log4net记录错误日志——使用线程列队写入
我的项目结构如下图: 日志帮助类库需要log4net包:工具—NuGet包管理器—管理解决方案NuGet程序包 线程日志帮助类 FlashLogger.cs 代码 using System; usin ...
- 【洛谷P3960】列队题解
[洛谷P3960]列队题解 题目链接 题意: Sylvia 是一个热爱学习的女孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Sylvia 所在的方阵中有 n×m ...
- [NOIP]2017列队——旋转treap/非旋转treap
Sylvia 是一个热爱学习的女孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Sylvia所在的方阵中有n × m名学生,方阵的行数为 n,列数为m. 为了便 ...
随机推荐
- jquery-uploadify传参方法
jquery-uploadify传参方法$(document).ready(function () { $("#uploadify").uploadify({ 'uploader' ...
- 前端工作准备-foxmail登陆失败汇总
foxmail 管理邮箱账号的一个工具软件, 但是在登陆的时候总是遇到明明账号密码没有问题,却总是报错,这里我登陆的时候的集中解决方法总结下: pop和imap 是邮箱的两种协议,大多选imap协议, ...
- HDU ACM Fibonacci
Problem Description Fibonacci numbers are well-known as follow: Now given an integer N, please find ...
- nodejs npm install -g 全局安装和非全局安装的区别
1. npm install xxx -g 时, 模块将被下载安装到[全局目录]中. [全局目录]通过 npm config set prefix "目录路径" 来设置. 比如说, ...
- MySQL分组条件,group by order by limit 顺序
having 中如果没有用聚合函数(必须sum,min),涉及到的字段名称必须在select 中有对应字段名称才可以,用到聚合函数可以不必在select中有相应字段名称的 limit 2,3:2表示从 ...
- init方法返回值自动改写问题
[init方法返回值自动改写问题] 在ARC开启的情况下,以init开头的实例方法的返回值会被默认无视,返回类型会被编译器改写为类指针类型. 如一人类叫UIButton类,如果一个方法叫 (UILab ...
- 玩转Mysql命令
连接数据库mysql -hlocalhost -uroot -p 在MYsql的跟目录文件下进行 show databses:展示所有数据库 解决方法1:在MySql安装目录下找到my.ini,将[m ...
- linux top 命令各参数详解
简介 top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于Windows的任务管理器. top显示系统当前的进程和其他状况,是一个动态显示过程,即可以通过用户按 ...
- 【摘自大型网站技术架构书】负载均衡时session如何共享
由于负载均衡服务器可能会将请求分发到集群任何一台服务器上,所以保证每次请求能够获得正确的session比单机时复杂. 集群环境下,session管理的主要几种手段 1.session复制 sessio ...
- 面试题:volatile关键字的作用、原理
在只有双重检查锁,没有volatile的懒加载单例模式中,由于指令重排序的问题,我确实不会拿到两个不同的单例了,但我会拿到“半个”单例. 而发挥神奇作用的volatile,可以当之无愧的被称为Java ...