可以直接用treap上大模拟...n+1个treap维护n行的前m-1个点和最后一列。

  需要支持删除一个点或者一段区间,而空间并不支持存下所有的点的时候,可以用一个点代替一个区间,记录区间首项的值和区间长度,这样每次查询某个点x的时候就可以用x在某个点y代表的区间里的rank来得到x的值,然后把x删去的时候,就把y这个区间从$[l,r]$拆分成$[l,x-1]$和$[x+1,r]$,重新加入。

  类似的题有NOI超级钢琴

#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<algorithm>
#define ll long long
#define int long long
#define lt tree[x].ls
#define rt tree[x].rs
using namespace std;
const int maxn=;
struct poi{ll beg; int rnd, size, ls, rs, len;}tree[maxn];
int n, m, Q, x, y, tott, tmp, rk;
ll ans;
int root[maxn], cnt[maxn], Len[maxn];
inline void read(int &k)
{
int f=; k=; char c=getchar();
while(c<'' || c>'') c=='-' && (f=-), c=getchar();
while(c<='' && c>='') k=k*+c-'', c=getchar();
k*=f;
}
inline void build(int &x, ll beg, int len)
{
tree[x=++tott].beg=beg; tree[x].size=;
tree[x].len=Len[x]=len;
tree[x].rnd=rand()<<|rand();
}
inline void up(int x)
{
tree[x].size=tree[lt].size+tree[rt].size+;
tree[x].len=tree[lt].len+tree[rt].len+Len[x];
}
void split(int x, int &l, int &r, int k)
{
if(!k) l=, r=x;
else if(tree[x].size==k) l=x, r=;
else if(tree[lt].size>=k) r=x, split(lt, l, lt, k), up(x);
else l=x, split(rt, rt, r, k-tree[lt].size-), up(x);
}
void rank(int x, int k)
{
if(tree[lt].len<k && tree[lt].len+Len[x]>=k) ans=k-tree[lt].len, rk+=tree[lt].size+;
else if(k<=tree[lt].len) rank(lt, k);
else rk+=tree[lt].size+, rank(rt, k-tree[lt].len-Len[x]);
}
void merge(int &x, int l, int r)
{
if(!l || !r) x=l+r;
else if(tree[l].rnd<tree[r].rnd) x=l, merge(rt, rt, r), up(x);
else x=r, merge(lt, l, lt), up(x);
}
inline void disc(int &Root, ll &poi, int pos)
{
int x, y;
rk=; rank(Root, pos);
split(Root, Root, y, rk); if(rk-) split(Root, Root, x, rk-); else x=Root;
if(ans-) build(tmp, tree[x].beg, ans-), merge(Root, Root, tmp);
if(Len[x]-ans) build(tmp, tree[x].beg+ans*(Root==root[n+]?m:), Len[x]-ans), merge(Root, Root, tmp);
merge(Root, Root, y); poi=x;
}
inline ll query(int posx, int posy)
{
if(posy!=m)
{
ll ANS, poi;
disc(root[posx], poi, posy); ANS=tree[poi].beg+ans-;
build(tmp, ANS, ); merge(root[n+], root[n+], tmp);
disc(root[n+], poi, posx); poi=tree[poi].beg+(ans-)*m;
build(tmp, poi, ); merge(root[posx], root[posx], tmp);
return ANS;
}
ll poi;
disc(root[n+], poi, posx); poi=tree[poi].beg+(ans-)*m;
build(tmp, poi, ); merge(root[n+], root[n+], tmp);
return poi;
}
#undef int
int main()
{
srand();
read(n); read(m); read(Q);
for(int i=;i<=n;i++) build(root[i], 1ll*+(i-)*m, m-); build(root[n+], m, n);
for(int i=;i<=Q;i++) read(x), read(y), printf("%lld\n", query(x, y));
}

  线段树好写很多,而且非常快。

  可以发现如果不是从最后一列加进来的数的话一定是递增的,那么这些数我们可以直接用n棵权值线段树来维护找第k大即可,把删点改为加点,就不会爆空间,然后剩下从最后一列加进来的直接丢进一个vector里面,如果查询的数不在线段树里就直接在vector里查询。最后一列维护的方法同理。

#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<algorithm>
#include<vector>
#define ll long long
#define lt tree[x].ls
#define rt tree[x].rs
using namespace std;
const int maxn=;
struct poi{int ls, rs, size;}tree[maxn<<];
vector<ll>h[maxn];
int n, m, q, tott, x, y;
ll mx;
int root[maxn];
inline void read(int &k)
{
int f=; k=; char c=getchar();
while(c<'' || c>'') c=='-' && (f=-), c=getchar();
while(c<='' && c>='') k=k*+c-'', c=getchar();
k*=f;
}
void update(int &x, int l, int r, int cx)
{
if(!x) x=++tott; tree[x].size++;
if(l==r) return;
int mid=(l+r)>>;
if(cx<=mid) update(lt, l, mid, cx);
else update(rt, mid+, r, cx);
}
int query(int x, int l, int r, int k)
{
if(l==r) return l;
int mid=(l+r)>>, lsize=mid-l+-tree[lt].size;
if(lsize>=k) return query(lt, l, mid, k);
return query(rt, mid+, r, k-lsize);
}
inline ll delr(int x, ll y)
{
ll pos=query(root[n+], , mx, x); update(root[n+], , mx, pos);
ll ans=pos<=n?1ll*pos*m:h[n+][pos-n-];
h[n+].push_back(y?y:ans);
return ans;
}
inline ll dell(int x, ll y)
{
ll pos=query(root[x], , mx, y); update(root[x], , mx, pos);
ll ans=pos<m?1ll*(x-)*m+pos:h[x][pos-m];
h[x].push_back(delr(x, ans));
return ans;
}
int main()
{
read(n); read(m); read(q); mx=max(n, m)+q;
for(int i=;i<=q;i++)
{
read(x); read(y);
if(y==m) printf("%lld\n", delr(x, ));
else printf("%lld\n", dell(x, y));
}
}

NOIP2017 Day2 T3 列队(treap)的更多相关文章

  1. 【NOIP 2017】Day2 T3 列队

    Problem Description \(Sylvia\) 是一个热爱学习的女孩子. 前段时间,\(Sylvia\) 参加了学校的军训.众所周知,军训的时候需要站方阵. \(Sylvia\) 所在的 ...

  2. [NOIp2017提高组]列队

    [NOIp2017提高组]列队 题目大意 一个\(n\times m(n,m\le3\times10^5)\)的方阵,每个格子里的人都有一个编号.初始时第\(i\)行第\(j\)列的编号为\((i-1 ...

  3. NOIP2017 Day1 T3 逛公园

    NOIP2017 Day1 T3 更好的阅读体验 题目描述 策策同学特别喜欢逛公园.公园可以看成一张\(N\)个点\(M\)条边构成的有向图,且没有 自环和重边.其中1号点是公园的入口,\(N\)号点 ...

  4. NOIP2017D2T3 列队—Treap

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

  5. 【NOIP题解】NOIP2017 TG D2T3 列队

    列队,NOIP2017 TG D2T3. 树状数组经典题. 题目链接:洛谷. 题意: Sylvia 是一个热爱学习的女孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. ...

  6. [NOIP2017 TG D2T3]列队

    题目大意:有一个$n \times m$的方阵,第$i$行第$j$列的人的编号是$(i-1) \times m + j$. 现在有$q$个出列操作,每次让一个人出列,然后让这个人所在行向左看齐,再让最 ...

  7. 【BZOJ 4518】【SDOI 2016 Round1 Day2 T3】征途

    比较明显的斜率优化DP,省选时因为时间太紧张和斜率DP写得不熟等原因只写了60分的暴力DP,其实当时完全可以对拍来检验标算的正确,但是我当时too naive- 很快打完了,调了将近一晚上QAQ,因为 ...

  8. 【NOIP 2013 DAY2 T3】 华容道(spfa)

    题目描述 [问题描述] 小 B 最近迷上了华容道,可是他总是要花很长的时间才能完成一次.于是,他想到用编程来完成华容道:给定一种局面, 华容道是否根本就无法完成,如果能完成, 最少需要多少时间. 小 ...

  9. 【NOIP 2015 DAY2 T3】 运输计划 (树链剖分-LCA)

    题目背景 公元 2044 年,人类进入了宇宙纪元. 题目描述 L 国有 n 个星球,还有 n-1 条双向航道,每条航道建立在两个星球之间,这 n-1 条航道连通了 L 国的所有星球. 小 P 掌管一家 ...

随机推荐

  1. Ubuntu 安装python后,安装python-dev

    1.通常情况下: sudo apt install python-dev 或者 在 sudo apt install python 命令下安装应该也附带了 python-dev 上述 pyhthon ...

  2. Ubuntu 16.04 主题美化及常用软件安装

    一.主题美化 系统清理 系统更新: 安装完系统之后,需要更新一些补丁.Ctrl+Alt+T调出终端,执行一下代码: sudo apt-get update sudo apt-get upgrade 卸 ...

  3. 原生WebGL场景中绘制多个圆锥圆柱

    前几天解决了原生WebGL开发中的一个问题,就是在一个场景中绘制多个几何网格特征不同的模型,比如本文所做的绘制多个圆锥和圆柱在同一个场景中,今天抽空把解决的办法记录下来,同时也附上代码.首先声明,圆柱 ...

  4. Codeforces 552 E. Two Teams

    E. Two Teams time limit per test 2 seconds memory limit per test 256 megabytes input standard input ...

  5. 基于C#的机器学习--颜色混合-自组织映射和弹性神经网络

    自组织映射和弹性神经网络 自组织映射(SOM),或者你们可能听说过的Kohonen映射,是自组织神经网络的基本类型之一.自组织的能力提供了对以前不可见的输入数据的适应性.它被理论化为最自然的学习方式之 ...

  6. spring-boot Jpa配置

    spring.jpa.hibernate.ddl-auto ddl-auto:create----每次运行该程序,没有表格会新建表格,表内有数据会清空 ddl-auto:create-drop---- ...

  7. We are writing to let you know we have removed your selling privileges

     Hello, We are writing to let you know we have removed your selling privileges, canceled your listin ...

  8. javascript event对象操作

    js代码: $(".leads_detail").click(function(e){ e = e || event; var t = e.target || e.srcEleme ...

  9. ie6下,莫名被复制出一段文字解决

    在IE6下使用浮动可能会出现文字重复的情况. 在IE6下,浮动层之间有注释文字的话,之前那个浮动层的内容文字就有可能遭遇一个“隐形”的复制,但是代码里查看文字可并没有多出来. 看个例子: HTML & ...

  10. scrum立会报告+燃尽图(第二周第五次)

    此作业要求参见:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2250 一.小组介绍 组名:杨老师粉丝群 组长:乔静玉 组员:吴奕瑶.公冶 ...