[Luogu3960][NOIP2017]列队
sol
震惊!\(NOIP\)居然也出数据结构!
话说回来,其实只需要对每一行的前\(m-1\)个人维护一个数据结构,然后对最后一列的\(m\)个人也维护一个数据结构就好了。具体的话写平衡树就可以了。
那么对于一次\((x,y)\)的操作,其实就是先把最后一列的第\(y\)个元素丢到第\(x\)行里面,再查出第\(x\)行的第\(y\)个元素,把他丢到最后一列的最后一个。
现在的问题是:根本开不了\(O(nm)\)的空间啊!
所以就把编号连续的所有点合并成一个点,这样的话初始时就只有\(n+n=2n\)个点,然后每次查询时会把一个点至多\(split\)成\(3\)个,所以总空间复杂度就是\(O(n)\)级别的。
时间复杂度一个\(\log\)。
code
#include<cstdio>
#include<algorithm>
using namespace std;
#define ll long long
int gi()
{
int x=0,w=1;char ch=getchar();
while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
if (ch=='-') w=0,ch=getchar();
while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
return w?x:-x;
}
const int N = 3e6+5;
int n,m,q,fa[N],ch[2][N],tot;
ll L[N],R[N],sz[N];
struct Splay{
int root;
int newnode(ll l,ll r)
{
++tot;
L[tot]=l;R[tot]=r;sz[tot]=r-l;
return tot;
}
void pushup(int x)
{
sz[x]=sz[ch[0][x]]+sz[ch[1][x]]+R[x]-L[x];
}
bool son(int x){return x==ch[1][fa[x]];}
void rotate(int x)
{
int y=fa[x],z=fa[y],c=son(x);
ch[c][y]=ch[c^1][x];if (ch[c][y]) fa[ch[c][y]]=y;
fa[x]=z;if (z) ch[son(y)][z]=x;
ch[c^1][x]=y;fa[y]=x;pushup(y);
}
void splay(int x)
{
for (int y=fa[x];y;rotate(x),y=fa[x])
if (fa[y]) son(x)^son(y)?rotate(x):rotate(y);
root=x;pushup(x);
}
int split(int x,ll k)
{
k+=L[x];int y=newnode(k,R[x]);R[x]=k;
if (!ch[1][x]) fa[ch[1][x]=y]=x;
else
{
x=ch[1][x];
while (ch[0][x]) x=ch[0][x];
fa[ch[0][x]=y]=x;
}
splay(y);return y;
}
ll popkth(ll k)
{
int x=root;
while (233)
{
if (k<=sz[ch[0][x]]) x=ch[0][x];
else
{
k-=sz[ch[0][x]];
if (k<=R[x]-L[x])
{
if (k<R[x]-L[x]) split(x,k);
if (k>1) x=split(x,k-1);
break;
}
else k-=R[x]-L[x],x=ch[1][x];
}
}
splay(x);
fa[ch[0][x]]=fa[ch[1][x]]=0;
if (!ch[0][x]) root=ch[1][x];
else
{
int y=ch[0][x];
while (ch[1][y]) y=ch[1][y];
splay(y);
root=fa[ch[1][y]=ch[1][x]]=y;
pushup(y);
}
return L[x];
}
void pushback(ll k)
{
int y=newnode(k,k+1);
if (!root) root=y;
else{
int x=root;
while (ch[1][x]) x=ch[1][x];
splay(x);
fa[ch[1][x]=y]=x;pushup(x);
}
}
}S[N];
int main()
{
n=gi();m=gi();q=gi();
for (int i=1;i<=n;++i) S[i].root=S[i].newnode(1ll*(i-1)*m+1,1ll*i*m);
for (int i=1;i<=n;++i) S[0].pushback(1ll*i*m);
while (q--)
{
int x=gi(),y=gi();ll ans;
S[x].pushback(S[0].popkth(x));
printf("%lld\n",ans=S[x].popkth(y));
S[0].pushback(ans);
}
return 0;
}
[Luogu3960][NOIP2017]列队的更多相关文章
- Luogu3960 NOIP2017列队(splay/线段树)
令splay中的一个点表示一段区间,需要使用其中某个点时将区间分裂即可,剩下的都是splay的基本操作了.写的非常丑陋,注意细节.感觉考场上肯定只能靠部分分苟活了.想起来去年因为各种莫名其妙的原因50 ...
- [NOIP2017]列队 离线+SBT
[NOIP2017]列队 题目描述 Sylvia 是一个热爱学习的女♂孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Sylvia 所在的方阵中有n×m名学生,方阵 ...
- 题解[NOIP2017] 列队
题解[NOIP2017] 列队 题面 解析 看到这题时感觉这个编号很难维护啊? 后来看了lzf大佬的题解才会.. 首先,考虑一个稍微暴力的做法, 维护每一行的前\(m-1\)个人和最后一列的\(n\) ...
- 【noip2017】【Luogu3960】列队 线段树
题目描述 Sylvia 是一个热爱学习的女♂孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Sylvia 所在的方阵中有 n \times mn×m 名学生,方阵的 ...
- NOIP2017列队(phalanx)解题报告
列队作为NOIP2017最后一道题,其实并不难,只是相对于其它题目,有点小小的工业 首先,这道题我用splay维护的,如果你不会splay,又想学一下splay,可以来这里学一学,接下来步入正题 首先 ...
- NOIP2017 列队 题解报告【56行线段树】
题目描述 Sylvia 是一个热爱学习的女♂孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Sylvia 所在的方阵中有n \times mn×m名学生,方阵的行数 ...
- [NOIP2017]列队 (Splay)
题目链接 NOIP2017真的是不按常理出牌: 1.数学题不在Day2T1 2.一道水题一道细节极多的模拟题一道不知道怎么形容的题(小凯的疑惑)(因为我太菜了) 3.3道大火题 当时看到列队这题是毫无 ...
- NOIP2017 列队
https://www.luogu.org/problemnew/show/P3960 p<=500 50分 模拟 每个人的出队只会影响当前行和最后一列 p<=500,有用的行只有500行 ...
- [NOIP2017] 列队(平衡树)
考虑转化题意: 设这次操作删掉点\((x, y)\) 对于每一次向左看齐:在第x行删除\((x, y)\),并将y以后的点全部前移一位 对于每一次向前看齐:x以后的点全部上移一位,并在最后一列插入\( ...
随机推荐
- Brain Network (easy)(并查集水题)
G - Brain Network (easy) Time Limit:2000MS Memory Limit:262144KB 64bit IO Format:%I64d & ...
- Android异步载入全解析之使用AsyncTask
Android异步载入全解析之使用AsyncTask 概述 既然前面提到了多线程,就不得不提到线程池,通过线程池,不仅能够对并发线程进行管理.更能够提高他们运行的效率.优化整个App.当然我们能够自己 ...
- 用NODEJS处理EXCEL文件导入导出,文件上传
參考文章 http://librajt.github.io/2013/08/04/handle-excel-file-with-nodejs/ 对照了 ExcelJS ,https://github. ...
- Android环境搭建 NDK+ADT(免cywgin)
JDK下载: 1下载地址 http://www.oracle.com/technetwork/java/javase/downloads/index.html 2配置环境变量 JAVA_HOME:创 ...
- You are using pip version 8.1.2, however version 9.0.1 is available.
[root@localhost ~]# pip install virtualenvmapperCollecting virtualenvmapper Could not find a versio ...
- centos 安装 jdk PostgreSQL
1.下载: anzhuang jDK http://blog.csdn.net/youzhouliu/article/details/51183115 ----------------------- ...
- Smarty模板的逻辑运算符号稍微做一下总结
对Smarty模板的逻辑运算符号稍微做一下总结,以备后用. eq equal : 相等neq not equal:不等于gt greater than:大于lt less th ...
- LeetCode:加一【66】
LeetCode:加一[66] 题目描述 给定一个由整数组成的非空数组所表示的非负整数,在该数的基础上加一. 最高位数字存放在数组的首位, 数组中每个元素只存储一个数字. 你可以假设除了整数 0 之外 ...
- Data Structure Array: Move all zeroes to end of array
http://www.geeksforgeeks.org/move-zeroes-end-array/ #include <iostream> #include <vector> ...
- DEDE 列表页调用如 标题,时间,简介等
以下是直接从板子中复制出来的,CSS自已根据需要写下就行.在调时简介长度不知道怎么控制,现在说下方法1. infolen='30' 这个可以2. 系统设置 >其它设置 >内容简介长度填下就 ...