loj #2319
noip2017列队 - resolve
标签:题解
\(n * m\) 的矩阵,每个元素 \((i, j)\) 的标号为 \((i - 1) * m + j\), 每次给出 \((x, y)\), 表示将查询此时处在 \(x\) 行 \(y\) 列元素的标号,并且删除此元素,接下来 \(x\) 行, \(y\) 列以后的元素左移,\(m\) 列,\(x\) 行以后的元素前移,显然此时 \((n, m)\) 空,将原先删除的 \((x, y)\) 元素放到 \((n, m)\)
输出每次查询
首先考虑一条链的情况
线段树维护 \(0 / 1\) 序列
将 \(x\) 列的元素放到最后
不考虑元素左移的情况(一条链只存在左移),这样的话如果一个元素被放到最后的位置,只需将第 \(x\) 个 \(1\) 变为 \(0\), 并且在线段树的最后的位置加入一个 \(1\), 这样的话区间的和就是区间元素的个数
列:
元素:1 2 3 4 5 6
维护:1 1 1 1 1 1
将第 3 列的数放到序列的最后
1 - 3 4 5 6 2
1 0 1 1 1 1 1
将第 3 列的数放到序列的最后
首先找到第 \(3\) 列的数,也就是第 \(3\) 个 \(1\) 的位置,此时这个位置的数为 \(4\)
1 - 3 - 5 6 2 4
1 0 1 0 1 1 1 1
推广
对每一行的前 \(m - 1\) 个元素开一颗线段树, 对最后一列开一颗线段树。
总共 \(n + 1\) 颗线段树
每颗线段树都维护这样的 \(0 / 1\) 序列代表每个位置元素的有无

操作:
对于询问是否是 \(m\) 列的有关询问分类处理
现在需要查询绿色区域,那么就将绿色区域的元素放到2号区域,相应地,绿色区域变成 \(0\), 2号区域变成 \(1\), 然后查询 \(m\) 列 \(x\) 行的元素放到1号区域,相应地红色区域变成 \(0\), 1号区域变为 \(1\)
如何处理元素的编号:
将每个点的编号记录下来是不可能的,这里只记录位置发生过改变的元素的编号,由于不会发生移动操作,所以没有改变的元素的编号是可以由行列的坐标得到的。只有发生元素的移动才会记录元素的编号。
对于空间
动态开节点
#include <bits/stdc++.h>
using namespace std;
const int N = 6e5 + 10;
int Lson[N * 30], Rson[N * 30], Size[N * 30], Root[N];
int Long[N];
int Seg;
int n, m, q;
int Len;
#define LL long long
LL Data[N * 30];
#define gc getchar()
inline int read() {int x = 0; char c = gc; while(c < '0' || c > '9') c = gc;
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = gc; return x;}
#undef gc
int now_x, now_y;
int Calc_size(int l, int r) {
if(now_y != m) {
if(r > Long[now_x]) return Long[now_x] - l + 1;
else return r - l + 1;
} else {
if(r > Long[n + 1]) return Long[n + 1] - l + 1;
else return r - l + 1;
}
}
LL Ans;
void Poi_A(int &rt, int l, int r, int x) {
if(!rt) {
rt = ++ Seg;
Size[rt] = Calc_size(l, r);
}
Size[rt] --;
if(l == r) {
if(Data[rt] != 0) Ans = Data[rt];
else {
if(now_y != m) Ans = (1ll * now_x - 1) * m + r;
else Ans = 1ll * r * m;
}
return ;
}
int mid = (l + r) >> 1;
int s_ = Lson[rt] ? Size[Lson[rt]] : Calc_size(l, mid);
if(x <= s_) Poi_A(Lson[rt], l, mid, x);
else if(Lson[rt]) Poi_A(Rson[rt], mid + 1, r, x - Size[Lson[rt]]);
else Poi_A(Rson[rt], mid + 1, r, x - Calc_size(l, mid));
}
void Poi_G(int &rt, int l, int r, int x, LL val) {
if(!rt) {
rt = ++ Seg;
Size[rt] = Calc_size(l, r);
} else Size[rt] ++;
if(l == r) {
Data[rt] = val;
return ;
}
int mid = (l + r) >> 1;
if(x <= mid) Poi_G(Lson[rt], l, mid, x, val);
else Poi_G(Rson[rt], mid + 1, r, x, val);
}
int main() {
n = read(), m = read(), q = read();
Len = max(n, m) + q;
for(int i = 1; i <= n; i ++) Long[i] = m - 1;
Long[n + 1] = n;
for(; q; q --) {
int xx = read(), yy = read();
now_x = xx, now_y = yy;
if(yy == m) {
Poi_A(Root[n + 1], 1, Len, xx);
cout << Ans << "\n";
Poi_G(Root[n + 1], 1, Len, ++ Long[n + 1], Ans);
} else {
Poi_A(Root[xx], 1, Len, yy);
cout << Ans << "\n";
LL Ans1 = Ans;
now_y = m;
Poi_A(Root[n + 1], 1, Len, xx);
now_y = yy;
Poi_G(Root[xx], 1, Len, ++ Long[xx], Ans);
now_y = m;
Poi_G(Root[n + 1], 1, Len, ++ Long[n + 1], Ans1);
}
}
return 0;
}
loj #2319的更多相关文章
- 2018.11.01 loj#2319. 「NOIP2017」列队(线段树)
传送门 唉突然回忆起去年去noipnoipnoip提高组试水然后省二滚粗的悲惨经历... 往事不堪回首. 所以说考场上真的有debuffdebuffdebuff啊!!!虽然当时我也不会权值线段树 这道 ...
- NOIP2017提高组Day2T3 列队 洛谷P3960 线段树
原文链接https://www.cnblogs.com/zhouzhendong/p/9265380.html 题目传送门 - 洛谷P3960 题目传送门 - LOJ#2319 题目传送门 - Vij ...
- 【SPOJ 2319】 BIGSEQ - Sequence (数位DP+高精度)
BIGSEQ - Sequence You are given the sequence of all K-digit binary numbers: 0, 1,..., 2K-1. You need ...
- 【HDOJ】2319 Card Trick
水题,STL双端队列. /* 2319 */ #include <iostream> #include <cstdio> #include <cstring> #i ...
- [Noi2016]区间 BZOJ4653 洛谷P1712 Loj#2086
额... 首先,看到这道题,第一想法就是二分答案+线段树... 兴高采烈的认为我一定能AC,之后发现n是500000... nlog^2=80%,亲测可过... 由于答案是求满足题意的最大长度-最小长 ...
- Loj #2192. 「SHOI2014」概率充电器
Loj #2192. 「SHOI2014」概率充电器 题目描述 著名的电子产品品牌 SHOI 刚刚发布了引领世界潮流的下一代电子产品--概率充电器: 「采用全新纳米级加工技术,实现元件与导线能否通电完 ...
- Loj #3096. 「SNOI2019」数论
Loj #3096. 「SNOI2019」数论 题目描述 给出正整数 \(P, Q, T\),大小为 \(n\) 的整数集 \(A\) 和大小为 \(m\) 的整数集 \(B\),请你求出: \[ \ ...
- Loj #3093. 「BJOI2019」光线
Loj #3093. 「BJOI2019」光线 题目描述 当一束光打到一层玻璃上时,有一定比例的光会穿过这层玻璃,一定比例的光会被反射回去,剩下的光被玻璃吸收. 设对于任意 \(x\),有 \(x\t ...
- Loj #3089. 「BJOI2019」奥术神杖
Loj #3089. 「BJOI2019」奥术神杖 题目描述 Bezorath 大陆抵抗地灾军团入侵的战争进入了僵持的阶段,世世代代生活在 Bezorath 这片大陆的精灵们开始寻找远古时代诸神遗留的 ...
随机推荐
- C++11 特性
之前工作中开发/维护的模块大多都是 "远古代码",只能编译 C++98,很多 C++11 的特性都忘得差不多了,再回顾一下 右值引用&转移语义: 消除两个对象交互时不必要的 ...
- Bootstrap4 入门
http://www.runoob.com/bootstrap4/bootstrap4-navs.html 共五个部分 1 <!DOCTYPE html> <html lang=&q ...
- 3_PHP表达式_5_数据类型转换_类型自动转换
以下为学习孔祥盛主编的<PHP编程基础与实例教程>(第二版)所做的笔记. PHP类型转换分为类型自动转换和类型强制转换. 1.布尔型数据参与算数运算时,TRUE被转换为整数1,FALSE被 ...
- 单例模式详解以及需要注意的地方(Singleton)
单例模式,顾名思义,就是在Java程序中只有唯一一个实例,这样做的好处是可以在不需要多个实例的对象采用单例模式可以节省内存,否则会造成不必要的内存浪费.单例模式的定义为:保证一个类只有一个实例,自己可 ...
- VBA字符串(十二)
字符串是一个字符序列,可以由字母,数字,特殊字符或全部字符组成. 如果一个变量被包含在双引号""中,则被认为是一个字符串. 语法 variable_name = "thi ...
- 上传图片,图片过大压缩处理以及解决自拍时会出现图片横屏的bug修复、长按保存图片
js部分:module.exports = { resize: function (file, callback, options) { //配置 options = Object.assign({ ...
- ArcGIS Runtime SDK for Android 定位权限(GPS定位\网络定位)
ACCESS_COARSE_LOCATION和ACCESS_FINE_LOCATION: android.permission.ACCESS_COARSE_LOCATION:是基站定位,即基于无线网络 ...
- Mysql语句练习记录
使用的sql图形软件:SQLyogEnt 使用的数据库:MYSQL5.7 软件地址: 链接:https://pan.baidu.com/s/1lajyXaSnmrO1v5v987NOoA 提取码:i3 ...
- Excel导入+写入数据库
1.引用服务 2.前端 <h2>这里是上传Excel功能页面</h2> <div> <form action="/Improve_Excel/get ...
- 四:MySQL系列之Python交互(四)
该篇主要介绍MySQL数据库的分表.以及与Python的交互的基本操作等. 一.拆分表操作 1.1 准备工作 创建数据库 --> 使用数据库 --> 创建数据表 --- 添加记录 -- ...