传送门

题意:给出一个长为$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 构造的更多相关文章

  1. bzoj 2530 [Poi2011]Party 构造

    2530: [Poi2011]Party Time Limit: 10 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 364  Solved:  ...

  2. BZOJ2214[Poi2011]Shift——模拟

    题目描述 Byteasar bought his son Bytie a set of blocks numbered from to and arranged them in a row in a ...

  3. BZOJ 2217: [Poi2011]Lollipop 构造 + 思维

    Description 有一个长度为n的序列a1,a2,...,an.其中ai要么是1("W"),要么是2("T").现在有m个询问,每个询问是询问有没有一个连 ...

  4. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  5. POI做题笔记

    POI2011 Conspiracy (2-SAT) Description \(n\leq 5000\) Solution 发现可拆点然后使用2-SAT做,由于特殊的关系,可以证明每次只能交换两个集 ...

  6. 洛谷P3516 PRZ-Shift [POI2011] 构造

    正解:构造 解题报告: 传送门! umm这题就是很思维的?就是想到了就A了想不到就做不出来,然而我也只能是做到理解不知道怎么想出来,,,感觉构造题什么的就很真诚,一点套路也没有,所以像我这种没有脑子只 ...

  7. 【BZOJ2530】[Poi2011]Party (xia)构造

    [BZOJ2530][Poi2011]Party Description 给定一张N(保证N是3的倍数)个节点M条边的图,并且保证该图存在一个大小至少为2N/3的团. 请输出该图的任意一个大小为N/3 ...

  8. bzoj 2528: [Poi2011]Periodicity【kmp+构造】

    神仙构造,做不来做不来 详见:http://vfleaking.blog.163.com/blog/static/174807634201329104716122/ #include<iostr ...

  9. 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 ...

随机推荐

  1. H5新标签(适合新手入门)

    H5新标签 文档类型设定 document HTML: sublime 输入 html:4s XHTML: sublime 输入 html:xt HTML5 sublime 输入 html:5 < ...

  2. VUE CLI 3.0 安装及创建项目

    一.安装 VUE CLI 3.0 官网: https://cli.vuejs.org/   详细资料可以自己先把官网过一遍. 1. 安装(默认你的电脑上已安装node及npm) npm install ...

  3. 即时消息服务框架(iMSF)应用实例之分布式事务三阶段提交协议的实现

    一,分布式事务简介 在当前互联网,大数据和人工智能的热潮中,传统企业也受到这一潮流的冲击,纷纷响应国家“互联网+”的战略号召,企业开始将越来越多的应用从公司内网迁移到云端和移动端,或者将之前孤立的IT ...

  4. loadrunner 脚本优化-加密与解密

    脚本优化-加密与解密 by:授客 QQ:1033553122   密码加密 可以给密码加密,意在把结果字符串作为脚本的参数或者参数值.例如,完整可能有一个用户密码填写的表单,你想测试网站针对不同密码的 ...

  5. Linux 学习笔记之超详细基础linux命令 Part 1

    Linux学习笔记之超详细基础linux命令 by:授客 QQ:1033553122   说明:主要是在REHL Server 6操作系统下进行的测试 --字符界面虚拟终端与图形界面之间的切 方法:[ ...

  6. 2018下半年Android面试历程

    个人看法:可以总结下他的面试经历以及涉及到的面试题 下面开始正文吧: 从今年下半年以来就开始在杭州准备简历找工作了,原因基本都懂的,没多少工资,投递简历的渠道是Boss,偶尔也在拉钩上投递,刚开始把简 ...

  7. Expo大作战(三十四)--expo sdk api之LinearGradient(线性渐变),KeepAwake(保持屏幕不休眠),IntentLauncherAndroid,Gyroscope,

    简要:本系列文章讲会对expo进行全面的介绍,本人从2017年6月份接触expo以来,对expo的研究断断续续,一路走来将近10个月,废话不多说,接下来你看到内容,讲全部来与官网 我猜去全部机翻+个人 ...

  8. docker常用命令整理-在容器中使用service命令

    在docker中使用centos镜像启动了容器并安装了相关软件,之后想用service命令启动相关服务却收到如下错误: Failed to get D-Bus connection: Operatio ...

  9. 03-12_MBean层次结构

    本文重点: Mbeans层次结构与WLST关系介绍 WebLogic Mbeans的类型 weblogic服务器的MBeans生命周期             Mbeans层次结构与WLST关系介绍: ...

  10. [HDFS_4] HDFS 的 Java 应用开发

    0. 说明 在 IDEA下 进行 HDFS 的 Java 应用开发 通过编写代码实现对 HDFS 的增删改查操作 1. 流程 1.1 在项目下新建 Moudle 略 1.2 为 Moudle 添加 M ...