[luogu P3960] [noip2017 d2t3] 队列

题目描述

Sylvia 是一个热爱学习的女♂孩子。

前段时间,Sylvia 参加了学校的军训。众所周知,军训的时候需要站方阵。

Sylvia 所在的方阵中有n \times mn×m名学生,方阵的行数为 nn,列数为 mm。

为了便于管理,教官在训练开始时,按照从前到后,从左到右的顺序给方阵中 的学生从 1 到 n \times mn×m 编上了号码(参见后面的样例)。即:初始时,第 ii 行第 jj 列 的学生的编号是(i-1)\times m + j(i−1)×m+j。

然而在练习方阵的时候,经常会有学生因为各种各样的事情需要离队。在一天 中,一共发生了 qq件这样的离队事件。每一次离队事件可以用数对(x,y) (1 \le x \le n, 1 \le y \le m)(x,y)(1≤x≤n,1≤y≤m)描述,表示第 xx 行第 yy 列的学生离队。

在有学生离队后,队伍中出现了一个空位。为了队伍的整齐,教官会依次下达 这样的两条指令:

  1. 向左看齐。这时第一列保持不动,所有学生向左填补空缺。不难发现在这条 指令之后,空位在第 xx 行第 mm 列。

  2. 向前看齐。这时第一行保持不动,所有学生向前填补空缺。不难发现在这条 指令之后,空位在第 nn 行第 mm 列。

教官规定不能有两个或更多学生同时离队。即在前一个离队的学生归队之后, 下一个学生才能离队。因此在每一个离队的学生要归队时,队伍中有且仅有第 nn 行 第 mm 列一个空位,这时这个学生会自然地填补到这个位置。

因为站方阵真的很无聊,所以 Sylvia 想要计算每一次离队事件中,离队的同学 的编号是多少。

注意:每一个同学的编号不会随着离队事件的发生而改变,在发生离队事件后 方阵中同学的编号可能是乱序的。

输入输出格式

输入格式:

输入共 q+1q+1 行。

第 1 行包含 3 个用空格分隔的正整数 n, m, qn,m,q,表示方阵大小是 nn 行 mm 列,一共发 生了 qq 次事件。

接下来 qq 行按照事件发生顺序描述了 qq 件事件。每一行是两个整数 x, yx,y,用一个空 格分隔,表示这个离队事件中离队的学生当时排在第 xx 行第 yy 列。

输出格式:

按照事件输入的顺序,每一个事件输出一行一个整数,表示这个离队事件中离队学 生的编号。

输入输出样例

输入样例#1: 复制

2 2 3
1 1
2 2
1 2 

输出样例#1: 复制

1
1
4

说明

【输入输出样例 1 说明】

列队的过程如上图所示,每一行描述了一个事件。 在第一个事件中,编号为 1 的同学离队,这时空位在第一行第一列。接着所有同学 向左标齐,这时编号为 2 的同学向左移动一步,空位移动到第一行第二列。然后所有同 学向上标齐,这时编号为 4 的同学向上一步,这时空位移动到第二行第二列。最后编号 为 1 的同学返回填补到空位中。

【数据规模与约定】

数据保证每一个事件满足 1 \le x \le n,1 \le y \le m1≤x≤n,1≤y≤m

sol明天补。。

upd:

首先,注意到nm都很大,怎么办?看似无从下手。

而注意到每一次操作都分2个阶段。

第一个阶段是修改(x,y)~(x,m),第二个阶段是修改(x,m)~(n,m)。

注意到这些操作又可以细分:

1.将(x,y)拿出并删除;

2.将(x,y+1)~(x,m)向前一格补上;

3.将(x,m+1)~(n,m)向上一格补上。

我们可以这样想,总操作次数是1e5级别的,说明改动次数少。

一次改动相当于把一个区间分为3段,删掉中间一段。这样,最后形成的总段数也不多。

又想到,splay能维护区间,那我们就可以建一堆splay,分别维护每一行的区间情况(当然要动态维护)。

又由于最后一列特殊,普通做法我们需要扫一遍每一个涉及到的行,效率底下。不如单独拉出来做一棵splay?

所以,最后我们要建n+1棵splay,每个splay中的每个节点表示一个区间。

其中对于第i棵(1<=i<=n)的节点,维护一个l,r,代表区间(化为一维编号)。

对于维护最后一列的splay,为了方便操作,也维护一个区间(单点成区间)。

然后我们需要的大操作有split,merge,splay,insert和erase。

具体实现可见代码。

code:

  1 %:pragma GCC optimize(2)
  2 #include <cstdio>
  3 #include <iostream>
  4 typedef long long LL;
  5
  6 void OJ_file() {
  7     #ifndef ONLINE_JUDGE
  8         freopen("in.txt","r",stdin);
  9         freopen("out.txt","w",stdout);
 10     #endif
 11 }
 12
 13 namespace fastIO {
 14     #define puc(c) putchar(c)
 15     inline int read() {
 16         int x=0; char ch=getchar();
 17         while (ch<'0'||ch>'9') ch=getchar();
 18         while (ch>='0'&&ch<='9') {
 19             x=(x<<3)+(x<<1)+ch-'0';
 20             ch=getchar();
 21         }
 22         return x;
 23     }
 24     int cnt,w[20];
 25     template <class T> inline void write(T x) {
 26         if (x==0) {
 27             puc('0'); return;
 28         }
 29         for (cnt=0; x; x/=10) w[++cnt]=x%10;
 30         for (; cnt; --cnt) puc(w[cnt]+48);
 31     }
 32     inline void newline() {
 33         puc('\n');
 34     }
 35 } using namespace fastIO;
 36
 37 const int N=300005;
 38 int n,m,q;
 39
 40 #define SplayTree node
 41 struct SplayTree {
 42     int s; LL l,r;
 43     node* c[3];
 44     node () {
 45         s=l=r=0;
 46         c[0]=c[1]=c[2]=0;
 47     }
 48 }*ro[N],*an;
 49 void newnode (node* &x,LL l,LL r) {
 50     x=new node(),x->s=r-l+1,x->l=l,x->r=r;
 51 }
 52 #define M ((l)+(r)>>1)
 53 void setup (node* &x,LL l,LL r) {
 54     newnode(x,l,r);
 55 }
 56 int len (node* x) {
 57     return x?x->r-x->l+1:0;
 58 }
 59 bool dir (node* x) {
 60     if (!x->c[2]) return 0;
 61     return x->c[2]->c[1]==x;
 62 }
 63 void refresh (node* x) {
 64     x->s=len(x);
 65     if (x->c[0]) x->s+=x->c[0]->s;
 66     if (x->c[1]) x->s+=x->c[1]->s;
 67 }
 68 void linknode (node* y,node* x,bool p) {
 69     if (x) x->c[2]=y;
 70     if (y) y->c[p]=x;
 71 }
 72 void rotate (node* x) {
 73     bool p=dir(x); node* y=x->c[2];
 74     linknode(y->c[2],x,dir(y));
 75     linknode(y,x->c[p^1],p);
 76     linknode(x,y,p^1);
 77     refresh(y),refresh(x);
 78 }
 79 void splay (node* x,int i) {
 80     if (x->c[2]==an) return;
 81     while (x->c[2]!=an) {
 82         if (x->c[2]->c[2]==an) {
 83             rotate(x);
 84             if (!an) ro[i]=x;
 85             return;
 86         }
 87         rotate(dir(x)^dir(x->c[2])?x:x->c[2]);
 88         rotate(x);
 89     }
 90     if (!an) ro[i]=x;
 91 }
 92 void insert (int i,LL v) {
 93     node* x=ro[i];
 94     if (!x) {
 95         newnode(ro[i],v,v);
 96         linknode(0,ro[i],1);
 97         return;
 98     }
 99     while (x->c[1]) x=x->c[1];
100     splay(x,i);
101     newnode(x,v,v);
102     linknode(ro[i],x,1);
103     refresh(ro[i]);
104 }
105 node* split (node* x,int i,int k) {
106     node* y,* t;
107     if (!x->c[1]) {
108         newnode(y,x->l+k,x->r);
109         linknode(x,y,1);
110         x->r=x->l+k-1,refresh(x);
111         splay(x->c[1],i);
112         return ro[i];
113     }
114     newnode(y,x->l+k,x->r);
115     t=x,x=x->c[1];
116     while (x->c[0]) x=x->c[0];
117     linknode(x,y,0);
118     t->r=t->l+k-1,refresh(t);
119     splay(x->c[0],i);
120     return ro[i];
121 }
122 node* erase (int i,int k) {
123     node* x=ro[i],* y; int s;
124     while (1) {
125         s=x->c[0]?x->c[0]->s:0;
126         if (k<=s) x=x->c[0]; else {
127             k-=s;
128             if (k<=len(x)) break; else {
129                 k-=len(x),x=x->c[1];
130             }
131         }
132     }
133     if (k!=len(x)) split(x,i,k);
134     if (k!=1) x=split(x,i,k-1);
135     splay(x,i);
136     newnode(y,x->l,x->l);
137     if (!x->c[0]) {
138         linknode(0,x->c[1],dir(x));
139         ro[i]=x->c[1];
140         return y;
141     }
142     x=x->c[0];
143     while (x->c[1]) x=x->c[1];
144     splay(x,i);
145     if (x->c[1]) linknode(x,x->c[1]->c[1],1);
146     refresh(x);
147     return y;
148 }
149
150 int main() {
151     OJ_file();
152     n=read(),m=read(),q=read(),an=0;
153     setup(ro[0],m,m);
154     for (int i=1; i<=n; ++i) {
155         setup(ro[i],(LL)(i-1)*m+1,(LL)i*m-1);
156     }
157     for (int i=2; i<=n; ++i) {
158         insert(0,(LL)i*m);
159     }
160     int X,Y; node* u;
161     for (; q; --q) {
162         X=read(),Y=read();
163         u=erase(0,X);
164         insert(X,u->l);
165         u=erase(X,Y);
166         insert(0,u->l);
167         write(u->l),newline();
168     }
169     return 0;
170 }

View Code

转载于:https://www.cnblogs.com/whc200305/p/7900727.html

[luogu P3960] [noip2017 d2t3] 队列相关推荐

  1. NOIP2017 Day2t3 队列

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

  2. [Luogu P3960] [UOJ 334] [NOIP 2017 tg]列队

    洛谷传送门 UOJ传送门 题目描述 Sylvia 是一个热爱学习的女孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Sylvia 所在的方阵中有n×mn \time ...

  3. [SinGuLaRiTy] NOIP2017 提高组

    [SinGuLaRiTy-1048] Copyright (c) SinGuLaRiTy 2018. All Rights Reserved. NOIP2017过了这么久,现在2018了才找到寒假这么 ...

  4. OI每周刷题记录——lrllrl

    看这标题就知道我是模仿的hzwer大佬,远程%%% 大佬的OI经历让蒟蒻我深受感触,为了晚一些AFO本蒟蒻也得加油了 从高二上期第一周开始计数,每个星期天更一次,一直更到我AFO 如果这是我此生最后一 ...

  5. 简单的题解 属2017

    -- 待补充 P3958 [NOIP2017 提高组] 奶酪 刷过,当时没一次过 因为没看出来是dfs,以及没有交代码前编译 P3959 [NOIP2017 提高组] 宝藏 两次没过,第三次过了,最后 ...

  6. BZOJ 2806 Luogu P4022 [CTSC2012]Cheat (广义后缀自动机、DP、二分、单调队列)

    题目链接: (bzoj) https://www.lydsy.com/JudgeOnline/problem.php?id=2806 (luogu) https://www.luogu.org/pro ...

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

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

  8. JZOJ 5456. 【NOIP2017提高A组冲刺11.6】奇怪的队列

    Description nodgd的粉丝太多了,每天都会有很多人排队要签名. 今天有n个人排队,每个人的身高都是一个整数,且互不相同.很不巧,nodgd今天去忙别的事情去了,就只好让这些粉丝们明天再来 ...

  9. [luogu 4292][bzoj 1758][WC2010] 重建计划(点分治 + dp + 单调队列优化 + 启发式合并)

    [WC2010]重建计划 problem solution code problem 洛谷指路 solution 一看那个道路平均价值的式子:AvgValue=∑e∈Sv(e)∣S∣\text{Avg ...

最新文章

  1. 测试基础 – 软件测试计划
  2. 51nod1008 N的阶乘 mod P(水题)
  3. 移动端H5页面注意事项
  4. CODE[VS]-求和-整数处理-天梯青铜
  5. python 垃圾回收详解
  6. docker 部署java_使用Docker堆栈部署的微服务-WildFly,Java EE和Couchbase
  7. 华为5G英国首秀,BBC主持人震惊了!到底网速有多快?
  8. linux上 arm开发环境搭建,详解 LINUX下QT For ARM开发环境搭建过程
  9. java hashSet
  10. Windows下secureCRT、putty使用秘钥登录Linux
  11. 睿远基金副总经理傅鹏博:用实业思维做投资 在认知范围之内做选择
  12. linux环境Git客户端下载安装
  13. 【JZOJ B组】【NOIP2013模拟】Heaven Cow与God Bull
  14. linux基本操作大全centos7
  15. Cheat Enginee(CE)的详细使用指南~包含下载安装教程以及核心功能讲解
  16. python后端开发学路线_【后端开发】Python要学哪些内容?Python程序员学习路线图...
  17. JAVA删除pdf空白页_如何从iText中的PDF中删除空白页面
  18. vue学习第五天(9月8号)
  19. 路由器/交换机flow 调试指令
  20. hive之生成唯一id

热门文章

  1. [Android] 解决Amd处理器 安装AndroidStudio并运行虚拟机
  2. linux软件不能通过验证,Linux上安装软件之前如何先验证软件包合法性呢?
  3. Redisson基本用法
  4. 使用二维码实现文件分享
  5. 关于python文件读写的路径问题
  6. android 版本变更,【专题分析】Android新版本重要变更
  7. 【 python手势识别项目 】百度云计算实现手势识别
  8. redis数据库安装、卸载。Python redis模块
  9. 期待黑色的Macbook吗?苹果研究MacBook的哑光黑色表面处理
  10. 有了这份人工智能思维导图书单,年薪百万不是梦