[luogu P3960] [noip2017 d2t3] 队列
[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 列的学生离队。
在有学生离队后,队伍中出现了一个空位。为了队伍的整齐,教官会依次下达 这样的两条指令:
向左看齐。这时第一列保持不动,所有学生向左填补空缺。不难发现在这条 指令之后,空位在第 xx 行第 mm 列。
- 向前看齐。这时第一行保持不动,所有学生向前填补空缺。不难发现在这条 指令之后,空位在第 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] 队列相关推荐
- NOIP2017 Day2t3 队列
Description Sylvia 是一个热爱学习的女孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Sylvia所在的方阵中有n × m名学生,方阵的行数为 n ...
- [Luogu P3960] [UOJ 334] [NOIP 2017 tg]列队
洛谷传送门 UOJ传送门 题目描述 Sylvia 是一个热爱学习的女孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Sylvia 所在的方阵中有n×mn \time ...
- [SinGuLaRiTy] NOIP2017 提高组
[SinGuLaRiTy-1048] Copyright (c) SinGuLaRiTy 2018. All Rights Reserved. NOIP2017过了这么久,现在2018了才找到寒假这么 ...
- OI每周刷题记录——lrllrl
看这标题就知道我是模仿的hzwer大佬,远程%%% 大佬的OI经历让蒟蒻我深受感触,为了晚一些AFO本蒟蒻也得加油了 从高二上期第一周开始计数,每个星期天更一次,一直更到我AFO 如果这是我此生最后一 ...
- 简单的题解 属2017
-- 待补充 P3958 [NOIP2017 提高组] 奶酪 刷过,当时没一次过 因为没看出来是dfs,以及没有交代码前编译 P3959 [NOIP2017 提高组] 宝藏 两次没过,第三次过了,最后 ...
- BZOJ 2806 Luogu P4022 [CTSC2012]Cheat (广义后缀自动机、DP、二分、单调队列)
题目链接: (bzoj) https://www.lydsy.com/JudgeOnline/problem.php?id=2806 (luogu) https://www.luogu.org/pro ...
- 【NOIP题解】NOIP2017 TG D2T3 列队
列队,NOIP2017 TG D2T3. 树状数组经典题. 题目链接:洛谷. 题意: Sylvia 是一个热爱学习的女孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. ...
- JZOJ 5456. 【NOIP2017提高A组冲刺11.6】奇怪的队列
Description nodgd的粉丝太多了,每天都会有很多人排队要签名. 今天有n个人排队,每个人的身高都是一个整数,且互不相同.很不巧,nodgd今天去忙别的事情去了,就只好让这些粉丝们明天再来 ...
- [luogu 4292][bzoj 1758][WC2010] 重建计划(点分治 + dp + 单调队列优化 + 启发式合并)
[WC2010]重建计划 problem solution code problem 洛谷指路 solution 一看那个道路平均价值的式子:AvgValue=∑e∈Sv(e)∣S∣\text{Avg ...
最新文章
- 测试基础 – 软件测试计划
- 51nod1008 N的阶乘 mod P(水题)
- 移动端H5页面注意事项
- CODE[VS]-求和-整数处理-天梯青铜
- python 垃圾回收详解
- docker 部署java_使用Docker堆栈部署的微服务-WildFly,Java EE和Couchbase
- 华为5G英国首秀,BBC主持人震惊了!到底网速有多快?
- linux上 arm开发环境搭建,详解 LINUX下QT For ARM开发环境搭建过程
- java hashSet
- Windows下secureCRT、putty使用秘钥登录Linux
- 睿远基金副总经理傅鹏博:用实业思维做投资 在认知范围之内做选择
- linux环境Git客户端下载安装
- 【JZOJ B组】【NOIP2013模拟】Heaven Cow与God Bull
- linux基本操作大全centos7
- Cheat Enginee(CE)的详细使用指南~包含下载安装教程以及核心功能讲解
- python后端开发学路线_【后端开发】Python要学哪些内容?Python程序员学习路线图...
- JAVA删除pdf空白页_如何从iText中的PDF中删除空白页面
- vue学习第五天(9月8号)
- 路由器/交换机flow 调试指令
- hive之生成唯一id