洛谷P3960 列队(Splay)
感觉自己好久不打数据结构已经完全不会了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)的更多相关文章
- 洛谷P3960 列队 Splay
其实思路并不算太难,就是代码量相对较大. 我们将一次离队转换为一次删除和两次加入,这样就可以保证空间是动态分配的,最大也不会暴空间. 说实话写之前感觉会很恶心,但是代码量就还好吧,有些细节需要特殊注意 ...
- 洛谷P3960 列队(NOIP2017)(Splay)
洛谷题目传送门 最弱的Splay...... 暴力模拟30分(NOIP2017实际得分,因为那时连Splay都不会)...... 发现只是一个点从序列里搬到了另一个位置,其它点的相对位置都没变,可以想 ...
- 洛谷 P3960 列队 解题报告
P3960 列队 题目描述 \(Sylvia\)是一个热爱学习的女♂孩子. 前段时间,\(Sylvia\)参加了学校的军训.众所周知,军训的时候需要站方阵. \(Sylvia\)所在的方阵中有\(n ...
- 洛谷P3960 列队 NOIp2017 线段树/树状数组/splay
正解:动态开点线段树 解题报告: 传送门! 因为最近学主席树的时候顺便get到了动态开点线段树?刚好想起来很久很久以前就想做结果一直麻油做的这题,,,所以就做下好了QAQ 然后说下,这题有很多种方法, ...
- 洛谷P3960 列队(动态开节点线段树)
题意 题目链接 Sol 看不懂splay..,看不懂树状数组... 只会暴力动态开节点线段树 观察之后不难发现,我们对于行和列需要支持的操作都是相同的:找到第\(k\)大的元素并删除,在末尾插入一个元 ...
- 洛谷 P3960 列队
https://www.luogu.org/problemnew/show/P3960 常数超大的treap #pragma GCC optimize("Ofast") #incl ...
- 洛谷 P3960 列队【线段树】
用动态开点线段树分别维护每一行和最后一列,线段树的作用是记录被选的点的个数以及查询第k个没被选的点,每次修改,从行里标记被选的点,从最后一列标记向左看齐之后少的点,然后用vector维护行列的新增点 ...
- 【洛谷P3960】列队题解
[洛谷P3960]列队题解 题目链接 题意: Sylvia 是一个热爱学习的女孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Sylvia 所在的方阵中有 n×m ...
- NOIP2017提高组Day2T3 列队 洛谷P3960 线段树
原文链接https://www.cnblogs.com/zhouzhendong/p/9265380.html 题目传送门 - 洛谷P3960 题目传送门 - LOJ#2319 题目传送门 - Vij ...
随机推荐
- 九度OJ 1093:WERTYU (翻译)
时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:1563 解决:609 题目描述: A common typing error is to place the hands on the ke ...
- Thread join方法的用途
主线程中会创建多个子线程做一些事情,主线程要用到这些子线程处理的数据,因此它需要等待所有的子线程处理完之后才继续运行.这就要用到join方法了.
- redis的主从复制和哨兵支持的主从切换
1 主从复制的目的是为了读写分离 master写,然后同步到slave,slave只管读. 2 哨兵存在的目的 是为了主从切换,如果master挂了,那么一个slave成为master,重启之后的ma ...
- Requires: libstdc++.so.6(GLIBCXX_3.4.15)(64bit)
Error: Package: mysql-community-server-8.0.12-1.el7.x86_64 (mysql80-community) Requires: libstdc++.s ...
- Linux就该这么学--命令集合4(文件目录管理命令)
1.touch命令用于创建空白文件与修改文件时间:(touch [选项] [文件]) 对于在Linux中的文件有三种时间: 更改时间(mtime):内容修改时间(不包括权限的) 更改权限(ctime) ...
- 云计算系列——HIVE1.2.1 - JDBC 服务
前提 Hadoop 集群已经启动 Hive1.2.1 环境已经搭建 一.启动 HIVE - JDBC 服务 hiveserver2 为 hive 的 jdbc 服务,此服务默认为前台进程,需要在执行 ...
- ABAP- INCLUDE Zxxx IF FOUND.
大顾代码: INCLUDE zinc_ca_0002 IF FOUND. - 这肯定是大顾问写出来的 - 一般都不会加东西啊 -加了 IF FOUND 不知道啥意思. 古道无仙(173120830) ...
- 代码空间项目 -- cookie的基本使用
cookie在日常开发b/s架构时候经常使用,可以在记住用户,方便自动登录,也可以记住用户的偏好并对应推送广告 下面说说开发时候的基本用法: 1.创建cookie//设置cookie,键值对形式Coo ...
- windows定时计划备份MySql
使用 MySql 的 mysqldump 将数据库文件备份成 sql 文件. Windows下备份 本地的数据库环境 MySql 安装环境:C:\MySql 数据库名称:bbs root root 数 ...
- WebDriver API——javascript的相关操作
有些时候webdriver是没法操作元素或浏览器的,这时候我们可以通过javascript来进行相关的操作,昨天在群里一个朋友定位一个显示框,总是无法定位点击,或者是点击无效,这个时候就可以用java ...