luogu P3960 列队
因为\(Splay\)可以\(O(logn)\)维护区间,所以直接对每一行维护第一个元素到倒数第二个元素的\(Splay\),最后一列维护一个\(Splay\),每次把选出来的点删掉,然后把那一行对应的在最后一列\(Splay\)的点接在这一行后面,然后把选出来的点接在最后一列最后
注意这里要动态开点,即一个点代表一段区间,每次询问再拆开所以我大力分类讨论,写了好长好久qwq
#include<bits/stdc++.h>
#define LL long long
#define il inline
#define re register
using namespace std;
const int N=300000+10;
il int rd()
{
int x=0,w=1;char ch=0;
while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
return x*w;
}
LL n,m,q;
int rt[N],tt,fa[N*4],ch[N*4][2],sz[N*4];
LL a[N*4][3];
il void psup(int x)
{
sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+a[x][0];
}
il void rot(int x)
{
int y=fa[x],z=fa[y],yy=ch[y][1]==x,w=ch[x][!yy];
ch[z][ch[z][1]==y]=x;fa[x]=z;
ch[y][yy]=w;fa[w]=y;
ch[x][!yy]=y,fa[y]=x;
psup(y),psup(x);
}
il void spl(int x,int en,int id)
{
if(!x) return;
while(fa[x]!=en)
{
int y=fa[x],z=fa[y];
if(z!=en) ((ch[y][1]==x)^(ch[z][1]==y))?rot(x):rot(y);
rot(x);
}
psup(x);
if(!en) rt[id]=x;
}
il int gkth(int x,int id)
{
if(x<=0||x>sz[rt[id]]) return 0;
int nw=rt[id];
while(233)
{
if(x<=sz[ch[nw][0]]) nw=ch[nw][0];
else if(x>sz[ch[nw][0]]+a[nw][0]) x-=sz[ch[nw][0]]+a[nw][0],nw=ch[nw][1];
else return spl(nw,0,id),nw;
}
}
il int bui(int l,int r)
{
if(l>r) return 0;
int mid=(l+r)>>1,nw=++tt;
sz[nw]=1,a[nw][0]=1,a[nw][1]=a[nw][2]=1ll*mid*m;
fa[ch[nw][0]=bui(l,mid-1)]=nw;
fa[ch[nw][1]=bui(mid+1,r)]=nw;
psup(nw);
return nw;
}
int main()
{
n=rd(),m=rd(),q=rd();
rt[0]=bui(1,n);
for(int i=1;i<=n;++i) rt[i]=++tt,a[tt][0]=sz[tt]=m-1,a[tt][1]=1ll*(i-1)*m+1,a[tt][2]=1ll*(i-1)*m+m-1;
while(q--)
{
int x=rd(),y=rd(),u;
if(y<m)
{
u=gkth(y,x);spl(u,0,x);
int len=a[u][0],szz=sz[ch[u][0]];
LL an=a[u][1]+(y-szz-1);
if(y>szz+1&&y<szz+len)
{
++tt,a[tt][0]=1,a[tt][1]=a[tt][2]=an;
a[u][0]=y-szz-1,a[u][2]=an-1,psup(u);
++tt,a[tt][0]=len-a[u][0]-1,a[tt][1]=an+1,a[tt][2]=a[u][1]+len-1;
ch[tt][1]=ch[u][1],fa[tt]=u,fa[ch[u][1]]=tt,ch[u][1]=tt;
psup(tt),psup(u);
int v=gkth(x,0);spl(v,0,0);
int w=gkth(sz[ch[v][0]],0);
if(w)
{
ch[w][1]=ch[v][1],fa[ch[v][1]]=w;
rt[0]=ch[v][0],ch[v][0]=ch[v][1]=fa[ch[v][0]]=0;
spl(w,0,0);
}
else
{
rt[0]=ch[v][1],ch[v][1]=fa[ch[v][1]]=0;
}
int z=gkth(m-2,x);
ch[z][1]=v,fa[v]=z;
spl(v,0,x);
z=gkth(n-1,0);
ch[z][1]=tt-1,fa[tt-1]=z,spl(tt-1,0,0);
}
else if(len==1)
{
int v,w=gkth(sz[ch[u][0]],x);
if(w)
{
ch[w][1]=ch[u][1],fa[ch[u][1]]=w;
rt[x]=ch[u][0],ch[u][0]=ch[u][1]=fa[ch[u][0]]=0;
spl(w,0,x);
}
else
{
rt[x]=ch[u][1],ch[u][1]=fa[ch[u][1]]=0;
}
v=gkth(x,0);spl(v,0,0);
w=gkth(sz[ch[v][0]],0);
if(w)
{
ch[w][1]=ch[v][1],fa[ch[v][1]]=w;
rt[0]=ch[v][0],ch[v][0]=ch[v][1]=fa[ch[v][0]]=0;
spl(w,0,0);
}
else
{
rt[0]=ch[v][1],ch[v][1]=fa[ch[v][1]]=0;
}
int z=gkth(m-2,x);
ch[z][1]=v,fa[v]=z,spl(v,0,x);
z=gkth(n-1,0);
ch[z][1]=u,fa[u]=z,spl(u,0,0);
}
else if(y==szz+len)
{
++tt,a[tt][0]=1,a[tt][1]=a[tt][2]=an;
--a[u][0],--a[u][2],psup(u);
int v=gkth(x,0);spl(v,0,0);
int w=gkth(sz[ch[v][0]],0);
if(w)
{
ch[w][1]=ch[v][1],fa[ch[v][1]]=w;
rt[0]=ch[v][0],ch[v][0]=ch[v][1]=fa[ch[v][0]]=0;
spl(w,0,0);
}
else
{
rt[0]=ch[v][1],ch[v][1]=fa[ch[v][1]]=0;
}
int z=gkth(m-2,x);
ch[z][1]=v,fa[v]=z;
spl(v,0,x);
z=gkth(n-1,0);
ch[z][1]=tt,fa[tt]=z,spl(tt,0,0);
}
else if(y==szz+1)
{
++tt,a[tt][0]=1,a[tt][1]=a[tt][2]=an;
--a[u][0],++a[u][1],psup(u);
int v=gkth(x,0);spl(v,0,0);
int w=gkth(sz[ch[v][0]],0);
if(w)
{
ch[w][1]=ch[v][1],fa[ch[v][1]]=w;
rt[0]=ch[v][0],ch[v][0]=ch[v][1]=fa[ch[v][0]]=0;
spl(w,0,0);
}
else
{
rt[0]=ch[v][1],ch[v][1]=fa[ch[v][1]]=0;
}
int z=gkth(m-2,x);
ch[z][1]=v,fa[v]=z;
spl(v,0,x);
z=gkth(n-1,0);
ch[z][1]=tt,fa[tt]=z,spl(tt,0,0);
}
printf("%lld\n",an);
}
else
{
u=gkth(x,0);
spl(u,0,0);
int v=gkth(sz[ch[u][0]],0);
if(v)
{
ch[v][1]=ch[u][1],fa[ch[u][1]]=v;
rt[0]=ch[v][0],ch[u][0]=ch[u][1]=fa[ch[u][0]]=0;
spl(v,0,0);
}
else
{
rt[0]=ch[u][1],ch[u][1]=fa[ch[u][1]]=0;
}
int z=gkth(n-1,0);
ch[z][1]=u,fa[u]=z,spl(u,0,0);
printf("%lld\n",a[u][1]);
}
}
return 0;
}
其他做法?咕咕咕
luogu P3960 列队的更多相关文章
- Luogu P3960 列队(动态开点线段树)
P3960 列队 题意 题目描述 Sylvia 是一个热爱学习的女孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Sylvia所在的方阵中有\(n \times m ...
- Luogu P3960 列队 线段树
题面 线段树入门题. 我们考虑线段树来维护这个矩阵. 首先我们先定n+1棵线段树前n棵维护每行前m-1个同学中没有离队过的同学,还有一棵维护第m列中没有离队过的同学.再定n+1棵线段树前n棵线段树维护 ...
- LUOGU P3960 列队 (noip2017 day2T3)
传送门 解题思路 记得当时考试我还是个孩子,啥也不会QAQ.现在回头写,用动态开点的线段树,在每行和最后一列开线段树,然后对于每次询问,把x行y列的删去,然后再把x行m列的元素加入x行这个线段树,然后 ...
- [luogu P3960] [noip2017 d2t3] 队列
[luogu P3960] [noip2017 d2t3] 队列 题目描述 Sylvia 是一个热爱学习的女♂孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Syl ...
- 洛谷 P3960 列队 解题报告
P3960 列队 题目描述 \(Sylvia\)是一个热爱学习的女♂孩子. 前段时间,\(Sylvia\)参加了学校的军训.众所周知,军训的时候需要站方阵. \(Sylvia\)所在的方阵中有\(n ...
- [LUOGU] [NOIP2017] P3960 列队
题目描述 Sylvia 是一个热爱学习的女孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Sylvia 所在的方阵中有 n \times mn×m 名学生,方阵的行 ...
- LOJ P3960 列队 树状数组 vector
https://www.luogu.org/problemnew/show/P3960 树状数组预处理之后直接搞就可以了,也不是很好解释,反正就是一个模拟过程的暴力用树状数组维护,还挺巧妙的. 我为什 ...
- 洛谷 P3960 列队
https://www.luogu.org/problemnew/show/P3960 常数超大的treap #pragma GCC optimize("Ofast") #incl ...
- luogu 3960 列队
noip2017 D2T3 列队 某zz选手当时直接放弃了写了50还写错了 题目大意: 有一个n行m列的方阵,第i行j列的点编号为(i-1)m+j 每次把第x行y列的点拿出来,然后把这一行它之后的点都 ...
随机推荐
- python之类的继承
# 类的的操作实例 # 子类ECar继承父类Car,并将实例Battery用作属性 class Car(): def __init__(self, name, model, year): self.n ...
- Bootstrap导航
前面的话 导航对于一位前端人员来说并不陌生.可以说导航是一个网站重要的元素组件之一,便于用户查找网站所提供的各项功能服务.本文将详细介绍Bootstrap导航 基础样式 Bootstrap框架中制作导 ...
- 洛谷P4088 [USACO18FEB]Slingshot
题面 大意:给出n个弹弓,可以用ti的时间把xi位置运到yi,在给出m组询问,求xj到yj最小时间. sol:首先如果不用弹弓,时间应为abs(xj-yj).否则时间就是abs(xi-xj)+abs( ...
- BZOJ2796[Poi2012]Fibonacci Representation——贪心+二分查找
题目描述 给出一个正整数x,问x最少能由多少个Fibonacci数加减算出. 例如1070=987+89-5-1,因此x=1070时答案是4. 输入 第一行一个正整数q (q<=10),表示有q ...
- bzoj2142: 礼物
2142: 礼物 Description 一年一度的圣诞节快要来到了.每年的圣诞节小E都会收到许多礼物,当然他也会送出许多礼物.不同的人物在小E心目中的重要性不同,在小E心中分量越重的人,收到的礼物会 ...
- android 开发中 sdk 无法更新
现在用到android 的多个版本适配 , 换了个新环境 , 重新配置了android 的开发环境,哪想到遇到了很多小问题. 今天又遇到了 android sdk manager 无法更新的问题. ...
- bzoj1002/luogu2144 轮状病毒 (dp)
给周围的点编号1到n 我们设f[i]为(1到i和中间点)连成一个联通块的情况数,那么有$f[i]=\sum{f[i-j]*j}$,就是从i-j+1到i里选一个连到中心,然后再把i-j+1到i连成链 但 ...
- Java -- JDBC 学习--获取数据库链接
数据持久化 持久化(persistence): 把数据保存到可掉电式存储设备中以供之后使用.大多数情况下,特别是企业级应用,数据持久化意味着将内存中的数据保存到硬盘上加以”固化”,而持久化的实现过程大 ...
- configParse模块(二十七)
configparser用于处理特定格式的文件,其本质上是利用open来操作文件. # 注释1 ; 注释2 [section1] # 节点 k1 = v1 # 值 k2:v2 # 值 [section ...
- [持续更新] 文章列表 Last Update: 8/21/2017
1.前端 HTML5快速学习二 Canvas@20141125 HTML5快速学习一@20141122 2.ASP.NET(MVC) MVC5+EF6 完整教程17--升级到EFCore2.0@201 ...