【NOIP2017】列队(Splay)

题面

洛谷

题解

其实好简单啊。。。

对于每一行维护一棵\(Splay\)

对于最后一列维护一棵\(Splay\)

\(Splay\)上一个节点表示一段区间

每次出去一个人就是把当前的\(Splay\)的一个节点拆分成\(3\)个

然后就很简单了。。

细节比较多。。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define ll long long
#define RG register
#define MAX 2000000
#define ls (t[x].ch[0])
#define rs (t[x].ch[1])
inline int read()
{
RG int x=0,t=1;RG char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=-1,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return x*t;
}
struct Node
{
int ch[2],ff;
ll size;
ll l,r;
}t[MAX];
int tot;
int n,m,Q;
struct SplayTree
{
int root;
int Node(ll l,ll r){++tot;t[tot].l=l;t[tot].r=r;t[tot].size=r-l;return tot;}
void pushup(int x){t[x].size=t[ls].size+t[rs].size+t[x].r-t[x].l;}
void rotate(int x)
{
int y=t[x].ff,z=t[y].ff;
int k=t[y].ch[1]==x;
if(z)t[z].ch[t[z].ch[1]==y]=x;t[x].ff=z;
t[y].ch[k]=t[x].ch[k^1];if(t[x].ch[k^1])t[t[x].ch[k^1]].ff=y;
t[x].ch[k^1]=y;t[y].ff=x;
pushup(y);pushup(x);
}
void Splay(int x)
{
for(int y=t[x].ff;y;rotate(x),y=t[x].ff)
if(t[y].ff)(rand()&1)?rotate(x):rotate(y);
root=x;
}
int Split(int x,ll K)
{
K+=t[x].l;
int y=Node(K,t[x].r);t[x].r=K;
if(!rs)t[y].ff=x,rs=y;
else
{
int u=rs;
while(t[u].ch[0])u=t[u].ch[0];
t[y].ff=u;t[u].ch[0]=y;
}
Splay(y);return y;
}
ll DelKth(ll K)
{
int x=root;
while(2333)
{
if(K<=t[ls].size)x=ls;
else
{
K-=t[ls].size;
if(K<=t[x].r-t[x].l)
{
if(K<t[x].r-t[x].l)Split(x,K);
if(K>1)x=Split(x,K-1);
break;
}
else K-=t[x].r-t[x].l,x=rs;
}
}
Splay(x);t[ls].ff=t[rs].ff=0;
if(!ls)root=rs;
else
{
int y=ls;
while(t[y].ch[1])y=t[y].ch[1];
Splay(y);
root=t[t[y].ch[1]=t[x].ch[1]].ff=y;
pushup(y);
}
return t[x].l;
}
void Insert(ll k)
{
int y=Node(k,k+1);
if(!root)root=y;
else
{
int x=root;
while(rs)x=rs;
Splay(x);
t[rs=y].ff=x;pushup(x);
}
}
}Splay[MAX];
int main()
{
n=read();m=read();Q=read();
for(int i=1;i<=n;++i)Splay[i].root=Splay[i].Node(1ll*i*m-m+1,1ll*i*m);
for(int i=1;i<=n;++i)Splay[0].Insert(1ll*i*m);
while(Q--)
{
int x=read(),y=read();ll ans;
Splay[x].Insert(Splay[0].DelKth(x));
printf("%lld\n",ans=Splay[x].DelKth(y));
Splay[0].Insert(ans);
}
return 0;
}

【NOIP2017】列队(Splay)的更多相关文章

  1. Luogu 3960 [NOIP2017] 列队 - splay|线段树

    题解 是我从来没有做过的裂点splay... 看的时候还是很懵逼的QAQ. 把最后一列的$n$个数放在一个平衡树中, 有 $n$ 个点 剩下的$n$行数, 每行都开一个平衡树,开始时每棵树中仅有$1$ ...

  2. 【loj2319】[NOIP2017]列队 Splay(卡过)

    题目描述 给出一个 $n\times m$ 的矩阵,第 $i$ 行第 $j$ 列的数为 $(i-1)\times m+j$ . 现在有 $q$ 次操作,每次操作给出位置 $(x,y)$ ,取出 $(x ...

  3. [NOIP2017]列队 离线+SBT

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

  4. 题解[NOIP2017] 列队

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

  5. [NOIP2017]列队 (Splay)

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

  6. 【NOIP2017】列队 splay

    当年太菜了啊,连$60$分的暴力都没拿满,只打了一个$30$分的. 考虑到这题最多只会询问到$30W$个点,且整个矩阵会去到$30W\times 30W$,显然不能将所有的点存下来. 对于每一行(除最 ...

  7. [NOIP2017]列队(线段树/裂点splay)

    考虑n=1的做法,就是支持: 1.在线删一个数 2.在结尾加一个数 3.查询序列的第y个数 用线段树记录区间内被删元素的个数,可以通过线段树上二分快速得解,对于新增的数,用vector记录即可. 对于 ...

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

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

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

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

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

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

随机推荐

  1. 【转】 mysql使用federated引擎实现远程访问数据库(跨网络同时操作两个数据库中的表)

    原文转自:http://www.2cto.com/database/201412/358397.html 问题: 这里假设我需要在IP1上的database1上访问IP2的database数据库内的t ...

  2. Linux☞权限数字表示法

    权限数字表示法: 1.Linux有三种访问权限: a.可读:r(Read) b.可写:w(Write) c.可执行:x(eXcute) 2.简单说说如何去看该文件的访问权限呢?一般我们执行命令,查看目 ...

  3. Unity Lighting - Reflections 反射(六)

      Reflections 反射 Reflection Source 反射源 By default, objects in a scene are rendered using Unity’s ‘St ...

  4. Paper Reading - Convolutional Sequence to Sequence Learning ( CoRR 2017 ) ★

    Link of the Paper: https://arxiv.org/abs/1705.03122 Motivation: Compared to recurrent layers, convol ...

  5. Centos7与Centos6的区别

    CentOS7 修改网卡名称为eth0.eth1 方法1 修改网卡名称 cd /etc/sysconfig/network-scripts/ mv ifcfg-eno16777736 ifcfg-et ...

  6. TCP的三次握手(建立连接)和四次挥手(关闭连接)(转)

    转自:(http://www.cnblogs.com/Jessy/p/3535612.html) 参照: http://course.ccniit.com/CSTD/Linux/reference/f ...

  7. pip安装Crypto注意事项

    pip install PyCrypto 1.使用pip install Crypto的方式安装的文件夹名称为crypto,而内部引用都用的Crypto路径,因此pip安装后,需要将文件夹名称修改为C ...

  8. B. Counting-out Rhyme(约瑟夫环)

    Description n children are standing in a circle and playing the counting-out game. Children are numb ...

  9. Java中的静态变量static

    package com.wangcf; public class Test { String name="你好"; static String sex="男"; ...

  10. Python:print()函数的几个常用参数

    1.参数sep:设置输出字符产之间的字符串.默认是空格 name='Tomwenxing' age=' job='student' print(name,age,job) print(name,age ...