考虑n=1的做法,就是支持:

1.在线删一个数

2.在结尾加一个数

3.查询序列的第y个数

用线段树记录区间内被删元素的个数,可以通过线段树上二分快速得解,对于新增的数,用vector记录即可。

对于满分同样如此,对每行开一个线段树,再对最后一列单独开一个。

对于每次操作:

若在最后一列:就是对最后一列直接使用n=1的做法。

若不在:对第x列的前m-1个用n=1的做法,再将最后一列的第x个加入第x列的末尾,然后再对最后一列使用n=1的做法。

 #include<cstdio>
#include<vector>
#include<algorithm>
#define lson ls[x],L,mid
#define rson rs[x],mid+1,R
#define rep(i,l,r) for (int i=(l); i<=(r); i++)
typedef long long ll;
using namespace std; const int N=,M=N*;
ll ans;
int n,m,Q,mx,x,y,nd,rt[N],sm[M],ls[M],rs[M];
vector<ll>V[N]; void ins(int &x,int L,int R,int pos){
if (!x) x=++nd;
if (L==R){ sm[x]++; return; }
int mid=(L+R)>>;
if (pos<=mid) ins(lson,pos); else ins(rson,pos);
sm[x]=sm[ls[x]]+sm[rs[x]];
} int que(int x,int L,int R,int pos){
if (L==R) return L;
int mid=(L+R)>>,t=mid-L+-sm[ls[x]];
if (t>=pos) return que(lson,pos); else return que(rson,pos-t);
} int main(){
scanf("%d%d%d",&n,&m,&Q); mx=max(n,m)+Q;
rep(i,,n) V[i].push_back();
while (Q--){
scanf("%d %d",&x,&y);
if (y==m){
int s=que(rt[],,mx,x);
if (s<=n) ans=1ll*s*m; else ans=V[][s-n];
printf("%lld\n",ans); ins(rt[],,mx,s); V[].push_back(ans);
continue;
}
int t=que(rt[x],,mx,y);
if (t<m) ans=1ll*(x-)*m+t; else ans=V[x][t-(m-)];
printf("%lld\n",ans); ins(rt[x],,mx,t);
int s=que(rt[],,mx,x); ll tmp=ans;
if (s<=n) ans=1ll*s*m; else ans=V[][s-n];
V[x].push_back(ans); ins(rt[],,mx,s); V[].push_back(tmp);
}
return ;
}

或裂点splay,一个点代表一个区间,每次删除某个位置k就将其裂为[l,k-1],k,[k+1,r]三个部分,再删掉k。

模板题。常数较大。

 #include<cstdio>
#include<algorithm>
#define rep(i,l,r) for (int i=(l); i<=(r); i++)
typedef long long ll;
using namespace std; const int N=;
int n,m,Q,nd,x,y,ch[N][],rt[N],f[N];
ll L[N],R[N],len[N]; int get(ll l,ll r){ nd++; L[nd]=l; R[nd]=r; len[nd]=r-l+; return nd; }
void upd(int x){ len[x]=len[ch[x][]]+len[ch[x][]]+R[x]-L[x]+; } void rot(int &rt,int x){
int y=f[x],z=f[y],w=ch[y][]==x;
if (y==rt) rt=x; else ch[z][ch[z][]==y]=x;
f[x]=z; f[y]=x; f[ch[x][w^]]=y;
ch[y][w]=ch[x][w^]; ch[x][w^]=y; upd(y);
} void splay(int &rt,int x){
while (x!=rt){
int y=f[x],z=f[y];
if (y!=rt) ((ch[z][]==y) ^ (ch[y][]==x)) ? rot(rt,x) : rot(rt,y);
rot(rt,x);
}
upd(x);
} void ins(int &rt,ll k){
int y=get(k,k);
if (!rt) { rt=y; return; }
int x=rt; while (ch[x][]) x=ch[x][];
splay(rt,x); f[y]=x; ch[x][]=y; upd(x);
} int split(int &rt,int x,ll k){
k+=L[x];
int y=get(k,R[x]); R[x]=k-;
if (!ch[x][]) f[y]=x,ch[x][]=y;
else{
int s=ch[x][];
while (ch[s][]) s=ch[s][];
f[y]=s; ch[s][]=y;
}
splay(rt,y); return y;
} int find(int x,ll &k){
if (k<=len[ch[x][]]) return find(ch[x][],k);
k-=len[ch[x][]];
if (k<=R[x]-L[x]+) return x; else return k-=R[x]-L[x]+,find(ch[x][],k);
} ll del(int &rt,ll k){
int x=find(rt,k);
if (k<R[x]-L[x]+) split(rt,x,k);
if (k>) x=split(rt,x,k-);
splay(rt,x); f[ch[x][]]=f[ch[x][]]=;
if (!ch[x][]) rt=ch[x][];
else{
int y=ch[x][]; rt=y;
while (ch[y][]) y=ch[y][];
splay(rt,y); ch[y][]=ch[x][];
f[ch[x][]]=y; upd(y);
}
return L[x];
} int main(){
freopen("phalanx.in","r",stdin);
freopen("phalanx.out","w",stdout);
scanf("%d%d%d",&n,&m,&Q);
rep(i,,n) rt[i]=++nd,L[i]=(i-1ll)*m+,R[i]=1ll*i*m-,len[i]=R[i]-L[i]+;
rep(i,,n) ins(rt[],1ll*i*m);
while (Q--){
scanf("%d%d",&x,&y); ll ans;
ins(rt[x],del(rt[],x));
printf("%lld\n",ans=del(rt[x],y));
ins(rt[],ans);
}
return ;
}

[NOIP2017]列队(线段树/裂点splay)的更多相关文章

  1. [NOIP2017]列队 线段树

    ---题面--- 题解: 之前写的splay,,,然而一直没调出来,我感觉是某个细节想错了,,然而已经重构4次代码不想再写splay了.于是今天尝试了线段树的解法. 首先因为每次出列之后的变化都是将当 ...

  2. 【BZOJ 3196】二逼平衡树 线段树套splay 模板题

    我写的是线段树套splay,网上很多人写的都是套treap,然而本蒟蒻并不会treap 奉上sth神犇的模板: //bzoj3196 二逼平衡树,支持修改某个点的值,查询区间第k小值,查询区间某个值排 ...

  3. BZOJ 3196 Tyvj 1730 二逼平衡树:线段树套splay

    传送门 题意 给你一个长度为 $ n $ 有序数列 $ a $ ,进行 $ m $ 次操作,操作有如下几种: 查询 $ k $ 在区间 $ [l,r] $ 内的排名 查询区间 $ [l,r] $ 内排 ...

  4. 刷题总结——二逼平衡树(bzoj3224线段树套splay)

    题目: Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:1.查询k在区间内的排名2.查询区间内排名为k的值3.修改某一位值上的数值4.查询k在 ...

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

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

  6. ZOJ-2112-Dynamic Rankings(线段树套splay树)

    题意: 完成两个操作: 1.询问一个区间里第k小的数: 2.修改数列中一个数的值. 分析: 线段树套平衡树,线段树中的每个节点都有一棵平衡树,维护线段树所记录的这个区间的元素.这样处理空间上是O(nl ...

  7. 【Luogu】P3380树套树模板(线段树套Splay)

    题目链接 幸甚至哉,歌以咏志. 拿下了曾经是那么遥不可及的线段树,学会了曾经高不可攀的平衡树,弄懂了装B的时候才挂在嘴边的树套树. 每道模板都是链上的一颗珠子.把它们挨个串起来,就成为我成长的历程. ...

  8. bzoj 3196 Tyvj 1730 二逼平衡树【线段树 套 splay】

    四舍五入就是个暴力. 对于线段树的每个区间都开一棵按权值排序的splay 对于第二个操作,二分一下,每次查询mid的排名,复杂度 $ O(nlog(n)^{3}) $ 其余的操作都是$ O(nlog( ...

  9. [BZOJ3196] [Tyvj1730] 二逼平衡树(线段树 套 Splay)

    传送门 至少BZOJ过了,其他的直接弃. 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 1.查询k在区间内的排名 2.查询区间内排名为k的值 3.修改某一位值上的 ...

随机推荐

  1. 【BZOJ】3524: [Poi2014]Couriers

    [算法]主席树 [题解]例题,记录和,数字出现超过一半就递归查找. 主席树见[算法]数据结构 #include<cstdio> #include<algorithm> #inc ...

  2. 在Unity中实现屏幕空间反射Screen Space Reflection(1)

    本篇文章我会介绍一下我自己在Unity中实现的SSR效果 出发点是理解SSR效果的原理,因此最终效果不是非常完美的(代码都是够用就行),但是从学习的角度来说足以学习到SSR中的核心算法. 如果对核心算 ...

  3. zedboard学习记录.1.纯PL流水灯

    环境:vivado 217.4 开发板: zedboard ver.d xc7z020clg484-1 1.打开Vivado新建一个RTL工程. 2.add source->add/create ...

  4. c语言学习笔记.条件编译.#if,#ifdef,if的区别

    最近遇到了,以此做个记录. 条件编译 是C预处理部分的内容. 其判断语句包括 #if  #else if  #else 以及 #ifdef 和 #endif. 使用 #if (表达式) codes1. ...

  5. CentOS 6.6下目录结构及其主要作用

    今天我们总结一下CentOS 6.6的linux的目录结构,一个系统的目录众多,这里我们主要认识一下,根目录下的主要目录,首先我们可以通过tree命令查看一次根目录下一层目录都有什么目录, 补充:不能 ...

  6. groovy的三个强劲属性(一)Gpath

            我们先从GPath开始,一个GPath是groovy代码的一个强劲对象导航的结构,名称的选择与XPath相似,XPath是一个用来描述XML(和等价物)文档的标准,正如XPath,GP ...

  7. selenium grid应用1-多浏览器执行用例

    driver =webdriver.Remote(command_executor=’http://127.0.0.1:4444/wd/hub’, desired_capabilities=Desir ...

  8. centos上Jenkins搭建

    Jenkins可以提供持续集成服务,它的运行环境(runtime)需要Tomcat和JDK 要把Jenkins让Tomcat启动服务,而Tomcat需要JDK的环境 详情配置参见: http://ww ...

  9. 服务器Java环境配置

    /* 当要在服务器里搭建Java web项目时, 要先配置好Java需要的环境 */ //jdk [root@localhost ~]# cd /usr/local/src [root@localho ...

  10. SyntaxError: Missing parentheses in call to 'print' 这个错误原因是Python版本问题

    问题 print "www.baidu.com"           Python2 print ("www.baidu.com")     Python3 出 ...