Luogu3516 POI2011 Shift 构造
题意:给出一个长为$N$的排列,有两种操作:$A$:将最后一个数字放到第一个;$B$:将第三个数字放到第一个。一次性使用某种操作$k$次写作$kA$或$kB$,其中在$kA$中$k < N$,在$kB$中$k < 3$。请给出一种方案使得序列变为$1,2,3...N$。$N \leq 2000$
一道比较难的构造题
我们考虑增量构造:假如我们已经将$1-i$排好了,如何将$i+1$排到它们后面。我们可以进行如下操作:
$1.$通过若干$A$操作将$i+1$放到序列开头的位置
$2.$重复$2A,1B$操作将$i$与$i+1$之间不必要的数字两两踢到$i+1$后面
$3.$如果序列最后还有一个多余的数字,使用$1A,2B$操作将它踢到$i+1$后面
这样$i$与$i+1$就能相连了。
但是当我们需要将$n-1$接上时,会有一些问题:
我们考虑这样的一个序列:$$n-1,1,2,3...n-2,n$$
如果我们使用$1A,2B$操作,$n$就会夹在$1$和$2$中间,打乱了我们之前排好的顺序。所以当我们需要排$n-1$和$n$时,这种方法是不可行的。不妨考虑另外一种构造方法。
我们将$n$移到第一个,也就是$$n,n-1,1,2,3...n-2$$
然后我们使用一次$2A,1B$操作,然后序列就变成了……
$$n,n-3,n-2,n-1,1,2,3...n-4$$
发现$n$的位置没有变,但是后面$n-1$个数在循环。那么我们不断重复该操作,直到序列变成$$n,1,2,3...n-2,n-1$$就行了。但实际上在当前情况下当$n$为奇数的时候是不可行的,因为在移动若干次之后,序列会变成$$n,2,3,4...n-1,1$$,再一次重复该操作又会把$n-1$踢到前面去了。
可以发现所有操作都是$O(n)$级别的,总操作次数是$O(n^2)$级别的,与题设刚好一致
稍微注意一下输出
关于序列移动的模拟操作建议使用链表。如果比较懒,可以使用STL中的deque,开O2的情况下效率还是比较优秀的(不开O2是最慢的)
下面的代码:O2 497ms,无O2 2146ms
#include<bits/stdc++.h> #define MAXN 5000010 using namespace std; inline int read(){ ; char c = getchar(); while(!isdigit(c)) c = getchar(); while(isdigit(c)){ a = (a << ) + (a << ) + (c ^ '); c = getchar(); } return a; } char done[MAXN] , allDone[MAXN]; int step[MAXN] , allStep[MAXN] , pot[MAXN] , N , cnt; deque < int > now; inline void moveA(int s){ if(done[cnt] != 'a') done[++cnt] = 'a'; step[cnt] += s; ; i <= s ; i++){ now.push_front(now.back()); now.pop_back(); } } inline void moveB(int s){ if(done[cnt] != 'b') done[++cnt] = 'b'; step[cnt] += s; ; i <= s ; i++){ ]; now[] = now[]; now[] = now[]; now[] = p; } } inline void output(){ ; ; i <= cnt ; i++) if(done[i] != allDone[i]){ )){ allDone[++calc] = done[i]; allStep[calc] = step[i]; } } else )) allStep[i] = (allStep[i] + step[i]) % (done[i] == ); else allDone[calc--] = ; cout << calc << endl; ; i <= calc ; i++) cout << allStep[i] << allDone[i] << ' '; } int main(){ N = read(); ; i <= N ; i++) now.push_back(read()); ){ putchar('); ; } else ){ cout << (now[] == ? " : "1\n1a"); ; } ; i < N - ; i++){ ; j < N ; j++) if(now[j] == i){ if(j) moveA(N - j); break; } ] != i - ) ] != i - ){ moveA(); moveB(); } else{ moveA(); moveB(); } } ; i < N ; i++) if(now[i] == N){ if(i) moveA(N - i); break; } ] == N - ){ ){ puts("NIE"); ; } ] != N - ){ moveA(); moveB(); } } moveA(N - ); output(); ; }
Luogu3516 POI2011 Shift 构造的更多相关文章
- bzoj 2530 [Poi2011]Party 构造
2530: [Poi2011]Party Time Limit: 10 Sec Memory Limit: 128 MBSec Special JudgeSubmit: 364 Solved: ...
- BZOJ2214[Poi2011]Shift——模拟
题目描述 Byteasar bought his son Bytie a set of blocks numbered from to and arranged them in a row in a ...
- BZOJ 2217: [Poi2011]Lollipop 构造 + 思维
Description 有一个长度为n的序列a1,a2,...,an.其中ai要么是1("W"),要么是2("T").现在有m个询问,每个询问是询问有没有一个连 ...
- bzoj AC倒序
Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...
- POI做题笔记
POI2011 Conspiracy (2-SAT) Description \(n\leq 5000\) Solution 发现可拆点然后使用2-SAT做,由于特殊的关系,可以证明每次只能交换两个集 ...
- 洛谷P3516 PRZ-Shift [POI2011] 构造
正解:构造 解题报告: 传送门! umm这题就是很思维的?就是想到了就A了想不到就做不出来,然而我也只能是做到理解不知道怎么想出来,,,感觉构造题什么的就很真诚,一点套路也没有,所以像我这种没有脑子只 ...
- 【BZOJ2530】[Poi2011]Party (xia)构造
[BZOJ2530][Poi2011]Party Description 给定一张N(保证N是3的倍数)个节点M条边的图,并且保证该图存在一个大小至少为2N/3的团. 请输出该图的任意一个大小为N/3 ...
- bzoj 2528: [Poi2011]Periodicity【kmp+构造】
神仙构造,做不来做不来 详见:http://vfleaking.blog.163.com/blog/static/174807634201329104716122/ #include<iostr ...
- Codeforces 960 二进制构造子序列 完全二叉树shift模拟 主席树/MAP DP
A #include <bits/stdc++.h> #define PI acos(-1.0) #define mem(a,b) memset((a),b,sizeof(a)) #def ...
随机推荐
- Centos 6.8 系统升级默认的Python版本
1.编译安装python2.7 # wget https://www.python.org/ftp/python/2.7.12/Python-2.7.12.tgz # Python-2.7.12.tg ...
- 《Inside C#》笔记(十三) 多线程 下
一 任务调度 当一个线程的时间片被用尽后,处理器会切换到另一个线程,但关于如何确定执行哪一个线程呢,这就涉及到了线程或任务的优先级. a) 每个线程都有优先级,任务调度算法会根据各线程的不同优先级来决 ...
- Java并发编程(八)同步容器
为了方便编写出线程安全的程序,Java里面提供了一些线程安全类和并发工具,比如:同步容器.并发容器.阻塞队列.Synchronizer(比如CountDownLatch) 一.为什么会出现同步容器? ...
- loadrunner录制的时候如何应对验证码的问题解决办法?
对这个问题,我个人的看法是,基本上可以考虑从三个途径来解决该问题: 1.第一种方法,也是最容易想到的,在被测系统中暂时屏蔽验证功能,也就是说,临时修改应用,无论用户输入的是什么验证码,都认为是正确的. ...
- 一种快速部署开发用oracle的办法
前段时间工作中需要在不少开发环境中快速提供开发可用的oracle环境,由于一一培训并部署原生oracle人力和时间成本过高,后来使用docker版本oracle,大大方便了开发工作的快速启动,方法记录 ...
- html 知识整理
一. 前言 本文全面介绍了html的定义.使用和具体常用标签. 参考资料:菜鸟教程 二.定义 html是HyperText Markup Language的简称,也就是超文本标记语言的缩写.通过htm ...
- early_suspend【转】
android 休眠唤醒机制分析(二) - early_suspend early_suspend是Android休眠流程的第一阶段即浅度休眠,不会受到wake_lock的阻止,一般用于关闭lcd.t ...
- Eclipse中定位当前文件在项目中的位置
点击红色框内的按钮,就能定位当前文件在项目中的位置, 另外, 找到位置后记得再点击一下这个按钮, 要不然每次打开一个文件都会自动定位
- java死锁示例及其发现方法
在java多线程编程中很容易出现死锁,死锁就是多个线程相互之间永久性的等待对方释放锁,这和数据库多个会话之间的死锁类似.下面的代码示例了一个最简单的死锁的例子,线程1和线程2相互之间等待对方释放锁来取 ...
- golang的reflection(转)
作者:BGbiao 链接:https://www.jianshu.com/p/42c19f88df6c 來源:简书 反射reflection 可以大大提高程序的灵活性,使得interface{}有更大 ...