传送门

感觉自己好久不打数据结构已经完全不会了orz……

据说正解树状数组?然而并不会

首先考虑一下每一次操作,就是把一个人从这一行中取出并放到行的最后,再从最后一列取出放到列的最后

那么这两种操作其实可以看做同一个类型,都是把某一个数取出并放到最后

那么这个可以用splay来搞,用splay维护区间,然后每一次找第k个相当于找第k大,然后删除之后在末尾插入

然后如果直接开空间怕是要炸……那只能缩点,等做到这个点的时候再把它split出来……

然后……看代码好了……

 //minamoto
#include<cstdio>
#include<iostream>
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;
#define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[<<],*p1=buf,*p2=buf;
inline int read(){
#define num ch-'0'
char ch;bool flag=;int res;
while(!isdigit(ch=getc()))
(ch=='-')&&(flag=true);
for(res=num;isdigit(ch=getc());res=res*+num);
(flag)&&(res=-res);
#undef num
return res;
}
char sr[<<],z[];int C=-,Z;
inline void Ot(){fwrite(sr,,C+,stdout),C=-;}
inline void print(ll x){
if(C><<)Ot();if(x<)sr[++C]=,x=-x;
while(z[++Z]=x%+,x/=);
while(sr[++C]=z[Z],--Z);sr[++C]='\n';
}
const int N=1e7+,maxn=3e5+;
int n,m,q,x,y;ll t,u;
int fa[N],ch[N][],tot;ll L[N],R[N],sz[N];
struct Splay{
#define ls ch[x][0]
#define rs ch[x][1]
int rt;
inline int newnode(ll l,ll r){
L[++tot]=l,R[tot]=r,sz[tot]=r-l+;return tot;
}
inline void upd(int x){
sz[x]=sz[ls]+sz[rs]+R[x]-L[x]+;
}
void rotate(int x){
int y=fa[x],z=fa[y],d=ch[y][]==x;
ch[z][ch[z][]==y]=x;
fa[x]=z,fa[y]=x,fa[ch[x][d^]]=y,ch[y][d]=ch[x][d^],ch[x][d^]=y,upd(y);
}
void splay(int x){
for(int y=fa[x],z=fa[y];fa[x];y=fa[x],z=fa[y]){
if(fa[y])
((ch[y][]==x)^(ch[z][]==y))?rotate(x):rotate(y);
rotate(x);
}
upd(x),rt=x;
}
inline void ins(ll v){
int x=rt;
while(rs) x=rs;
newnode(v,v),fa[tot]=x,rs=tot,splay(tot);
}
ll split(int x,ll k){
ll s=L[x],t=R[x];
if(k!=s&&k!=t){
if(s+<t){
int a=newnode(k+,t);R[x]=k-;
ch[a][]=ch[x][],ch[x][]=a,fa[a]=x,upd(a),upd(x);
splay(a);
}else{++L[x],splay(x);}
}else{
k==t?--t:++s;
L[x]=s,R[x]=t,sz[x]=t-s+,splay(x);
}
return k;
}
ll rk(int k){
int x=rt;
while(true){
if(sz[ls]>=k) x=ls;
else{
k-=sz[ls];
if(k<=R[x]-L[x]+) return split(x,k+L[x]-);
k-=R[x]-L[x]+,x=rs;
}
}
}
inline void init(ll l,ll r){rt=newnode(l,r);}
int build(int l,int r,int f){
if(l>r) return ;
int mid=(l+r)>>,x=newnode(1ll*m*mid,1ll*m*mid);
fa[x]=f;
ls=build(l,mid-,x);
rs=build(mid+,r,x);
return upd(x),x;
}
}T[maxn];
int main(){
// freopen("testdata.in","r",stdin);
n=read(),m=read(),q=read();
for(int i=;i<=n;++i) T[i].init(1ll*(i-)*m+,1ll*i*m-);
T[].rt=T[].build(,n,);
while(q--){
x=read(),y=read();
if(y==m){
print(u=T[].rk(x)),T[].ins(u);
}else{
print(u=T[x].rk(y));
t=T[].rk(x);
T[x].ins(t),T[].ins(u);
}
}
Ot();
return ;
}

洛谷P3960 列队(Splay)的更多相关文章

  1. 洛谷P3960 列队 Splay

    其实思路并不算太难,就是代码量相对较大. 我们将一次离队转换为一次删除和两次加入,这样就可以保证空间是动态分配的,最大也不会暴空间. 说实话写之前感觉会很恶心,但是代码量就还好吧,有些细节需要特殊注意 ...

  2. 洛谷P3960 列队(NOIP2017)(Splay)

    洛谷题目传送门 最弱的Splay...... 暴力模拟30分(NOIP2017实际得分,因为那时连Splay都不会)...... 发现只是一个点从序列里搬到了另一个位置,其它点的相对位置都没变,可以想 ...

  3. 洛谷 P3960 列队 解题报告

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

  4. 洛谷P3960 列队 NOIp2017 线段树/树状数组/splay

    正解:动态开点线段树 解题报告: 传送门! 因为最近学主席树的时候顺便get到了动态开点线段树?刚好想起来很久很久以前就想做结果一直麻油做的这题,,,所以就做下好了QAQ 然后说下,这题有很多种方法, ...

  5. 洛谷P3960 列队(动态开节点线段树)

    题意 题目链接 Sol 看不懂splay..,看不懂树状数组... 只会暴力动态开节点线段树 观察之后不难发现,我们对于行和列需要支持的操作都是相同的:找到第\(k\)大的元素并删除,在末尾插入一个元 ...

  6. 洛谷 P3960 列队

    https://www.luogu.org/problemnew/show/P3960 常数超大的treap #pragma GCC optimize("Ofast") #incl ...

  7. 洛谷 P3960 列队【线段树】

    用动态开点线段树分别维护每一行和最后一列,线段树的作用是记录被选的点的个数以及查询第k个没被选的点,每次修改,从行里标记被选的点,从最后一列标记向左看齐之后少的点,然后用vector维护行列的新增点 ...

  8. 【洛谷P3960】列队题解

    [洛谷P3960]列队题解 题目链接 题意: Sylvia 是一个热爱学习的女孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Sylvia 所在的方阵中有 n×m ...

  9. NOIP2017提高组Day2T3 列队 洛谷P3960 线段树

    原文链接https://www.cnblogs.com/zhouzhendong/p/9265380.html 题目传送门 - 洛谷P3960 题目传送门 - LOJ#2319 题目传送门 - Vij ...

随机推荐

  1. STL algorihtm算法iter_swap(29)

    iter_swap原型: std::iter_swap template <class ForwardIterator1, class ForwardIterator2> void ite ...

  2. Grid++Report设置显示固定行数

    一.要实现的功能打印的报表显示固定的行数,并且设置字段的文字可以自动换行二.设置步骤1.鼠标左键单击“明细网格”栏,在右侧属性窗口中设置“追加空白行”属性值为:是:“追加空白行在后”属性值为:是.2. ...

  3. js 数据获取

    http://www.cnhan.com/shantui/templates/MC500/TP001/js/template.js var qiaoContent="0";//0默 ...

  4. 【Effective C++】资源管理

    资源:动态分配的内存.文件描述器.互斥锁.图形界面中的字型与笔刷.数据库连接以及网络sockets等,无论哪一种资源,重要的是,当你不再使用它时,必须将它还给系统. 条款13:以对象管理资源 当我们向 ...

  5. seventBus(封装) 一个巧妙的解决vue同级组件通讯的思路

    如果在你项目中需要多处用到同级组件通讯,而又不想去写繁琐的vuex,可以参考这个小思路.本人在写项目中琢磨出来的,感觉挺好用,分享一下. 1.在utils文件夹下添加BusEvent.js 注释已经很 ...

  6. iPhone HTTP获得XML并使用GDataXML解析

    1. [代码][C/C++]代码     NSURL *url = [NSURL URLWithString:  @"http://www.raywenderlich.com/downloa ...

  7. 脚踏实地学C#5-扩展方法

    扩展方法(Extension Method) MSDN定义:能够向现有类型“添加”方法,而无需创建新的派生类型.重新编译或以其他方式修改原始类型. 扩展方法须知: 1.扩展方法声明所在的类必须被声明为 ...

  8. linux应用之yum命令详解

    linux yum命令详解 yum(全称为 Yellow dog Updater, Modified)是一个在Fedora和RedHat以及SUSE中的Shell前端软件包管理器.基於RPM包管理,能 ...

  9. Dom4J 解析xml ,类查询

    /** * 从XML文件比对,传入provinceId 返回 provinceShortName * @param provinceid * @return */ public static Stri ...

  10. TModJS:使用tmodjs

    ylbtech-TModJS:使用tmodjs 1.返回顶部 1. 1.安装 npm install -g tmodjs 2.配置 我的模板都放在tpl文件夹中,htmls用于存放模板页面,每一个后缀 ...