[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以后的点全部上移一位,并在最后一列插入\( ...
随机推荐
- MySQL 下 ROW_NUMBER / DENSE_RANK / RANK 的实现
原文链接:http://hi.baidu.com/wangzhiqing999/item/7ca215d8ec9823ee785daa2b MySQL 下 ROW_NUMBER / DENSE_RAN ...
- GridView 显示行号 设置行号列的宽度
/// <summary> /// GridView 显示行号 设置行号列的宽度 /// </summary> /// <param name="gv" ...
- Struts中类型转换踩的坑
出现的异常: 当我输入的数据很大时候,转换后如上,这并不是我想要的, 出现问题的原因: Struts2对常用的数据类型如String.Integer.Double等都添加了转换器进行对应的转换操作. ...
- React-Native在gitHub下载的Demo不能运行问题!!!
1.目前找到的最可行的运行React-Native Demo的解决方案 请参考:http://blog.csdn.net/shubinniu/article/details/52873250 2.检查 ...
- Linux kernel config and makefile system
转载自:http://blog.csdn.net/dreamxu/article/details/6125545 http://www-900.ibm.com/developerWorks/cn/li ...
- vim下的ctags和taglist等的使用和配置
1.ctags (1)到 http://prdownloads.sourceforge.net/ctags/ctags-5.6.tar.gz 下载ctags源码ctags-5.6.ta ...
- SpringBoot学习笔记(4):添加自定义的过滤器
SpringBoot:学习笔记(4)——添加自定义的过滤器 引入自定义过滤器 SpringBoot提供的前端控制器无法满足我们产品的需求时,我们需要添加自定义的过滤器. SpringBoot添加过滤器 ...
- foreign key
http://sevenseacat.net/2015/02/24/add_foreign_key_gotchas.html https://robots.thoughtbot.com/referen ...
- python cookbook 字符串和文本
使用多个界定符分隔字符串 import re line = 'asdf fjdk; afed, fjek,asdf, foo' print(re.split(r'[;,\s]\s*', line)) ...
- Data Structure Binary Tree: Boundary Traversal of binary tree
http://www.geeksforgeeks.org/boundary-traversal-of-binary-tree/ #include <iostream> #include & ...