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 列队的更多相关文章

  1. 关于PHP堆栈与列队

    在PHP中数组常被当作堆栈(后进先出:LIFO)与队列(先进先出:FIFO)结构来使用.PHP提供了一组函数可以用于push与pop(堆栈)还有shift与unshift(队列)来操作数组元素.堆栈与 ...

  2. 在PHP中如何使用消息列队

    /** * 消息列队服务 * @author zhou.tingze * @example * -----------------------------------Create----------- ...

  3. BZOJ2720: [Violet 5]列队春游

    2720: [Violet 5]列队春游 Time Limit: 5 Sec  Memory Limit: 128 MBSubmit: 173  Solved: 125[Submit][Status] ...

  4. [NOIp 2017]列队

    Description Sylvia 是一个热爱学习的女孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Sylvia 所在的方阵中有$n \times m$名学生, ...

  5. NOIP2017D2T3 列队—Treap

    NOIP2017列队 Description Sylvia 是一个热爱学习的女孩子.  前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Sylvia所在的方阵中有n × m ...

  6. P2649 - 【NOIP2017】列队

    Description Sylvia 是一个热爱学习的女孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Sylvia 所在的方阵中有 n×m 名学生,方阵的行数为 ...

  7. WebForm应用log4net记录错误日志——使用线程列队写入

    我的项目结构如下图: 日志帮助类库需要log4net包:工具—NuGet包管理器—管理解决方案NuGet程序包 线程日志帮助类 FlashLogger.cs 代码 using System; usin ...

  8. 【洛谷P3960】列队题解

    [洛谷P3960]列队题解 题目链接 题意: Sylvia 是一个热爱学习的女孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Sylvia 所在的方阵中有 n×m ...

  9. [NOIP]2017列队——旋转treap/非旋转treap

    Sylvia 是一个热爱学习的女孩子.  前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Sylvia所在的方阵中有n × m名学生,方阵的行数为 n,列数为m.  为了便 ...

随机推荐

  1. Patator-一款很好用的爆破工具

    项目地址:https://github.com/lanjelot/patator 打开文件夹 运行一下文件查看帮助 python patator.py --help 这里有很多的爆破选项,就不一一截图 ...

  2. java - 读取,导出 excel文件数据

    首先需下载poi java包,添加至构建路径, 写处理方法: import java.io.FileInputStream;import java.io.FileOutputStream;import ...

  3. delphi 四舍五入

    trunc取整 四舍五入 formatfloat('0.00', 2.1850) 看第二位,然后对后面的数字处理,偶数的话舍去,奇数四舍五入 System.Math.RoundTo(tempval,- ...

  4. 数据库与vs的连接

    新建一个MFC基于对话框的项目后,更改属性, 其中需要将include(里面都是MySQL的头文件)lib是库文件,将.dll放入与.exe同级目录下,或放入系统里(c:\windows\system ...

  5. Linux常用基本命令 1

    useradd 创建用户. password 修改密码. date 查看时间 man date 帮助文档.f往后翻 b往前翻 q退出.软修改 man hwclock 修改硬件时钟, cal 查看日历 ...

  6. 168. Excel Sheet Column Title 由数字返回excel的标题

    [抄题]: Given a positive integer, return its corresponding column title as appear in an Excel sheet. F ...

  7. SpringMVC第二天

    SpringMVC第二天   框架课程 1. 课程计划 1.高级参数绑定 a) 数组类型的参数绑定 b) List类型的绑定 2.@RequestMapping注解的使用 3.Controller方法 ...

  8. _GNU_SOURCE宏

    打开_GNU_SOURCE这个宏可以打开一些功能,比如为了在Linux系统上编译使用带有检测文件type的宏(S_ISxxxx): S_ISREG() //传入stat结构的st_mode,下同.是否 ...

  9. jquery数组拼接

    var a=[]; var c=[80,90,70,100] var b={'张三':19,'成绩':c}; a.push(b); console.log("测试案例",a); 同 ...

  10. Python2.X和Python3.X文件对话框、下拉列表的不同

    Python2.X和Python3.X文件对话框.下拉列表的不同 今天初次使用Python Tkinter来做了个简单的记事本程序.发现Python2.x和Python3.x的Tkinter模块的好多 ...