可以直接用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. java nio实现文件复制

    public class TransferTo { public static void main(String[] args) throws Exception { FileChannel in = ...

  2. Qt-QML-Canvas-雷达扫描仪表简单

    使用QML实现的雷达仪表的实现,主要实现了余晖扫描的实现,其他的还是比较简单的,后面可能会加入目标标识,目前的功能仅仅是一个假的扫描雷达 来看代码 /* 作者:张建伟 时间:2018年4月27日 简述 ...

  3. robotframework 脚本编写规范

    测试集.脚本 测试脚本的名字不要超过20个字符,文件类型应该为txt  名字必需易读且有意义(看名知意)  记住测试集的名字是自动根据文件.目录的名字创建的.后缀名会被截去,下划线会转换为空格,如果名 ...

  4. PHASER3 设置场景SCENE SLEEPING休眠和WAKE唤醒

    A good way to set scene stop when hidden and run while visible again ! 使用sleep和wake方法的好处: 1.可以彻底让sce ...

  5. Vue2 v-bind:href 中如何使用过滤器

    <a class="topic_title" v-bind:href="info.id|getTitleHref" v-bind:title=" ...

  6. HttpServlet 详解(基础)

    HttpServlet详解 大家都知道Servlet,但是不一定很清楚servlet框架,这个框架是由两个Java包组成:javax.servlet和javax.servlet.http. 在java ...

  7. listagg wm_concat 行转列

    一. 这个写法和wm_concat相似,listagg(day,',')要把哪一列转换为同一行within group (order by day)同一行如何排序 with temp as ( ' d ...

  8. 前端获取URL和SESSON中的值

    .CS中代码 public ActionResult Index(string viewname, bool partial = false) { //获取URL中的 foreach (var key ...

  9. FivePlus——分工理解

    最终的游戏方案 游戏采用回合制,每回合双方英雄各自轮流选择移动和攻击以及大招,选择结束进行结算 英雄/小兵/塔的攻击力/大招效果参照作业要求,如果发现不均衡再进行调整 UI界面考虑使用QT或者命令行界 ...

  10. MySql 8 命令

    1-创建用户 create user 用户名@'%' identified by '密码'; create user 用户名@'localhost' identified by '密码';   2-授 ...