题面

线段树入门题。

我们考虑线段树来维护这个矩阵。

首先我们先定n+1棵线段树前n棵维护每行前m-1个同学中没有离队过的同学,还有一棵维护第m列中没有离队过的同学。再定n+1棵线段树前n棵线段树维护每行因一个同学离队而从第m列插♂进来的同学,还有一棵维护到队尾的同学。

具体怎么维护?比如当前的询问是(x,y),先分两种情况:

1.不在第m列。

那么我们就先看看这个同学是不是插♂进来,是的话就在那后n+1棵线段树的第x棵里找,不然就在前n+1棵的第x棵里找。

然后在对应线段树的对应位置里删除离队的同学,将第m列的第x行的那个同学(需要先判断是在前n+1棵里的第n+1棵还是后n+1棵)插♂到后n+1棵线段树的第x棵的最后,再把他原先所在的那个线段树里对应的位置删掉。最后把离队的同学插♂到后n+1棵线段树的第n+1棵的最后。

2.在第m列

先判断是在前n+1棵里的第n+1棵还是后n+1棵,然后他所在的那个线段树里对应的位置删掉,最后把离队的同学插♂到后n+1棵线段树的第n+1棵的最后。

//by zykykyk
#include<cstdio>
#include<ctime>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<string>
#include<cstring>
#define rg register
#define il inline
#define vd void
#define ll long long
#define N 300010
#define For(i,x,y) for (rg int i=(x);i<=(y);i++)
#define Dow(i,x,y) for (rg int i=(x);i>=(y);i--)
#define cross(i,k) for (rg int i=first[k];i;i=last[i])
using namespace std;
il ll max(ll x,ll y){return x>y?x:y;}
il ll min(ll x,ll y){return x<y?x:y;}
il ll read(){
ll x=;int ch=getchar(),f=;
while (!isdigit(ch)&&(ch!='-')&&(ch!=EOF)) ch=getchar();
if (ch=='-'){f=-;ch=getchar();}
while (isdigit(ch)){x=(x<<)+(x<<)+ch-'';ch=getchar();}
return x*f;
}
int n,m,q,x,y; int Tot,Rt[N],Sum[N*],Lson[N*],Rson[N*],cnt[N];
ll V[N*];
il vd Update(int &u,int l,int r,int ql,ll x,int k){
if (!u) u=++Tot;Sum[u]+=k;
if (l==r){V[u]=x;return;}
int mid=l+r>>;
if (ql<=mid) Update(Lson[u],l,mid,ql,x,k);
else Update(Rson[u],mid+,r,ql,x,k);
}
il ll Query(int u,int l,int r,int k){
if (l==r) return V[u];
int mid=l+r>>;
if (Sum[Lson[u]]>=k) return Query(Lson[u],l,mid,k);
else return Query(Rson[u],mid+,r,k-Sum[Lson[u]]);
}
il int Query_id(int u,int l,int r,int k){
//printf("l=%d r=%d Sum[Lson[u]]=%d\n",l,r,Sum[Lson[u]]);
if (l==r) return l;
int mid=l+r>>;
if (Sum[Lson[u]]>=k) return Query_id(Lson[u],l,mid,k);
else return Query_id(Rson[u],mid+,r,k-Sum[Lson[u]]);
} int tot,rt[N],v[N*],lson[N*],rson[N*];
il vd update(int &u,int l,int r,int ql,int k){
if (!u) u=++tot;v[u]+=k;
if (l==r) return;
int mid=l+r>>;
if (ql<=mid) update(lson[u],l,mid,ql,k);
else update(rson[u],mid+,r,ql,k);
}
il ll query(int u,int l,int r,int k){
if (l==r) return l;
int mid=l+r>>,V=mid-l+-v[lson[u]];
if (V>=k) return query(lson[u],l,mid,k);
else return query(rson[u],mid+,r,k-V);
} il ll work(int x,ll y){
ll ans;
if (n-v[rt[n+]]>=x){
ll X=query(rt[n+],,n,x);
ans=X*(1ll*m);
update(rt[n+],,n,X,);//printf("X=%lld\n",X);
}
else {
ans=Query(Rt[n+],,q,x-n+v[rt[n+]]);//printf("%d 233\n",Query_id(Rt[n+1],1,q,x-n+v[rt[n+1]]));
Update(Rt[n+],,q,Query_id(Rt[n+],,q,x-n+v[rt[n+]]),,-);
}
cnt[n+]++;
Update(Rt[n+],,q,cnt[n+],y?y:ans,);
return ans;
}
il ll Work(int x,int y){
ll ans;
if (m--v[rt[x]]>=y){
ll X=query(rt[x],,m-,y);
ans=1ll*(x-)*m+X;
update(rt[x],,m-,X,);
}
else {
ans=Query(Rt[x],,q,y-(m--v[rt[x]]));
Update(Rt[x],,q,Query_id(Rt[x],,q,y-(m--v[rt[x]])),,-);
}
cnt[x]++;
ll k=work(x,ans);Update(Rt[x],,q,cnt[x],k,);//printf("k=%lld\n",k);
return ans;
} int main(){
freopen("phalanx.in","r",stdin);
freopen("phalanx.out","w",stdout);
n=read(),m=read(),q=read();
For(i,,q){
x=read(),y=read();
if (y==m) printf("%lld\n",work(x,));
else printf("%lld\n",Work(x,y));
}
}

Luogu P3960 列队 线段树的更多相关文章

  1. Luogu P3960 列队(动态开点线段树)

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

  2. 洛谷 P3960 [ NOIP 2017 ] 列队 —— 线段树

    题目:https://www.luogu.org/problemnew/show/P3960 NOIP 题,不用很复杂的数据结构...但又参考了许多: 要求支持维护删除第 k 个和在末尾插入的数据结构 ...

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

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

  4. [Luogu] 可持久化线段树 1(主席树)

    https://www.luogu.org/problemnew/show/P3834 #include<cstdio> #include<iostream> #include ...

  5. Luogu P5280 [ZJOI2019]线段树

    送我退役的神题,但不得不说是ZJOIDay1最可做的一题了 先说一下考场的ZZ想法以及出来后YY的优化版吧 首先发现每次操作其实就是统计出增加的节点个数(原来的不会消失) 所以我们只要统计出线段树上每 ...

  6. luogu 1712 区间(线段树+尺取法)

    题意:给出n个区间,求选择一些区间,使得一个点被覆盖的次数超过m次,最小的花费.花费指的是选择的区间中最大长度减去最小长度. 坐标值这么大,n比较小,显然需要离散化,需要一个技巧,把区间转化为半开半闭 ...

  7. [NOIP2017]列队(线段树/裂点splay)

    考虑n=1的做法,就是支持: 1.在线删一个数 2.在结尾加一个数 3.查询序列的第y个数 用线段树记录区间内被删元素的个数,可以通过线段树上二分快速得解,对于新增的数,用vector记录即可. 对于 ...

  8. [NOIP2017]列队 线段树

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

  9. Luogu P1471 方差 线段树

    那是上上周...也是重构了四遍...后来GG了...今天又拾起,搞了搞终于过了... 好吧就是个线段树,公式懒得推了https://www.cnblogs.com/Jackpei/p/10693561 ...

随机推荐

  1. PACM Team(牛客第三场多校赛+dp+卡内存+打印路径)

    题目链接(貌似未报名的不能进去):https://www.nowcoder.com/acm/contest/141/A 题目: 题意:背包题意,并打印路径. 思路:正常背包思路,不过五维的dp很容易爆 ...

  2. 21、python操作redis的模块?

    什么是redis? redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合).zset(s ...

  3. Codeforces Round #483 (Div. 1) 简要题解

    来自FallDream的博客,未经允许,请勿转载,谢谢. 为了证明一下我又来更新了,写一篇简要的题解吧. 这场比赛好像有点神奇,E题莫名是道原题,导致有很多选手直接过掉了(Claris 表演24s过题 ...

  4. mysql 之修改初始密码

    转载自:https://www.cnblogs.com/ivictor/p/5142809.html 为了加强安全性,MySQL5.7为root用户随机生成了一个密码,在error log中,关于er ...

  5. ogre3d环境配置 SDK安装配置及简单事例教程

    ogre3d环境配置 SDK安装配置及简单事例教程 http://www.cr173.com/html/22594_1.html ogre3d环境配置 SDK安装配置及简单事例教程 http://ww ...

  6. python之requests库使用问题汇总

    一.请求参数类型 1.get requests.get(url, data, cookies=cookies) url:字符串: data:字典类型,可以为空: cookies:字典类型,可以为空: ...

  7. Makefile系列之四 :条件判断

    一.示例 下面的例子,判断$(CC)变量是否“gcc”,如果是的话,则使用GNU函数编译目标. libs_for_gcc = -lgnu normal_libs = foo: $(objects) i ...

  8. PostGIS pgrouting路径分析

    --让数据库支持PostGIS和pgRouting的函数和基础表(安装后第一次使用时执行,以后都不再执行) CREATE EXTENSION postgis; CREATE EXTENSION pgr ...

  9. [ Python ] set集合及函数的使用

    1. set类型 set 和 dict 类似,也是一组 key 的集合,但是不存储 value. 由于 key  不重复,所以,在 set 中, 没有重复的 key 集合是可变类型 (1)集合的创建 ...

  10. leetcode 121 122 123 . Best Time to Buy and Sell Stock

    121题目描述: 解题:记录浏览过的天中最低的价格,并不断更新可能的最大收益,只允许买卖一次的动态规划思想. class Solution { public: int maxProfit(vector ...