luogu

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

  1. Luogu3960 NOIP2017列队(splay/线段树)

    令splay中的一个点表示一段区间,需要使用其中某个点时将区间分裂即可,剩下的都是splay的基本操作了.写的非常丑陋,注意细节.感觉考场上肯定只能靠部分分苟活了.想起来去年因为各种莫名其妙的原因50 ...

  2. [NOIP2017]列队 离线+SBT

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

  3. 题解[NOIP2017] 列队

    题解[NOIP2017] 列队 题面 解析 看到这题时感觉这个编号很难维护啊? 后来看了lzf大佬的题解才会.. 首先,考虑一个稍微暴力的做法, 维护每一行的前\(m-1\)个人和最后一列的\(n\) ...

  4. 【noip2017】【Luogu3960】列队 线段树

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

  5. NOIP2017列队(phalanx)解题报告

    列队作为NOIP2017最后一道题,其实并不难,只是相对于其它题目,有点小小的工业 首先,这道题我用splay维护的,如果你不会splay,又想学一下splay,可以来这里学一学,接下来步入正题 首先 ...

  6. NOIP2017 列队 题解报告【56行线段树】

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

  7. [NOIP2017]列队 (Splay)

    题目链接 NOIP2017真的是不按常理出牌: 1.数学题不在Day2T1 2.一道水题一道细节极多的模拟题一道不知道怎么形容的题(小凯的疑惑)(因为我太菜了) 3.3道大火题 当时看到列队这题是毫无 ...

  8. NOIP2017 列队

    https://www.luogu.org/problemnew/show/P3960 p<=500 50分 模拟 每个人的出队只会影响当前行和最后一列 p<=500,有用的行只有500行 ...

  9. [NOIP2017] 列队(平衡树)

    考虑转化题意: 设这次操作删掉点\((x, y)\) 对于每一次向左看齐:在第x行删除\((x, y)\),并将y以后的点全部前移一位 对于每一次向前看齐:x以后的点全部上移一位,并在最后一列插入\( ...

随机推荐

  1. Java Enum 比较用 == 还是 eques

    我是把枚举当作常量来使用的,枚举中还有两个自己的属性,关注到这个地方的朋友对枚举已经有了认识,这里就不再编写枚举的demo了,这里我直接说结果吧,在枚举中使用==和equals比较效果是一样的,查看源 ...

  2. 【BZOJ4033】[HAOI2015]树上染色 树形DP

    [BZOJ4033][HAOI2015]树上染色 Description 有一棵点数为N的树,树边有边权.给你一个在0~N之内的正整数K,你要在这棵树中选择K个点,将其染成黑色,并将其他的N-K个点染 ...

  3. Redis主从、事务、哨兵、消息、代理分片

    安装 wget http://download.redis.io/releases/redis-3.0.5.tar.gz tar -zxvf redis-3.0.5.tar.gz cd redis-3 ...

  4. springboot工程的结构

    1 springboot的工程结构是什么 就是我们组织springboot工程时遵循的代码的目录结构. 2 spring initializr创建的工程的目录结构 源码目录:src/main/java ...

  5. js滚动到指定位置显示或隐藏元素

    $(function(){ $(window).scroll(function(){ var scroll_top=$(window).scrollTop(); console.log(scroll_ ...

  6. 【python】-- 类的反射

    反射 反射我们以后会经常用到,这个东西实现了动态的装配,通过字符串来反射类中的属性和方法 一.反射函数 1.hasarttr(obj,name_str) 作用:判断一个对象obj中是否有对应的name ...

  7. CF1060 E-Sergey and Subway

    题目戳这里 一句话题意 一棵树,任意相隔一个点的两个点连一条新边(原边留下),问所有点对的距离之和. Solution 本来看见是黑题有点怕,但仔细一想也没有那么难. 先处理出每个点的深度(dep)和 ...

  8. 使用oracle10g官方文档找到监听文件(listener.ora)的模板

    ***********************************************声明*************************************************** ...

  9. go语言之并发编程 channel

    前面介绍了goroutine的用法,如果有多个goroutine的话相互之间是如何传递数据和通信的呢.在C语言或者JAVA中,传输的方法包括共享内存,管道,信号.而在Go语言中,有了更方便的方法,就是 ...

  10. oracle 查询重复数据并且删除, 只保留一条数据重复数据

    最近面试中都遇到了这样一个数据库题: 删除表中的重复数据,有且只保留一条重复数据. 思路: 1)这个题需要用到rowid,首先找到重复数据的rowid,并找出rowid最大或最小值,作为删除的条件: ...