问题描述

小A有一个1-2N的排列A[1..2N],他希望将A数组从小到大排序,小A可以执行的操作有N种,每种操作最多可以执行一次,对于所有的

i(1<=i<=N),第i中操作为将序列从左到右划分为2{N-i+1}段,每段恰好包括2{i-1}个数,然后整体交换其中两段.小A想知道可以将数组A从小到

大排序的不同的操作序列有多少个,小A认为两个操作序列不同,当且仅当操作个数不同,或者至少一个操作不同(种类不同或者操作位置不同).

下面是一个操作事例:

N=3,A[1..8]=[3,6,1,2,7,8,5,4].

第一次操作,执行第3种操作,交换A[1..4]和A[5..8],交换后的A[1..8]为[7,8,5,4,3,6,1,2].

第二次操作,执行第1种操作,交换A[3]和A[5],交换后的A[1..8]为[7,8,3,4,5,6,1,2].

第三次操作,执行第2中操作,交换A[1..2]和A[7..8],交换后的A[1..8]为[1,2,3,4,5,6,7,8].

输入格式

第一行,一个整数N第二行,2N个整数,A[1..2N]。

输出格式

一个整数表示答案

样例输入

3

7 8 5 6 1 2 4 3

样例输出

6

数据范围

100%的数据, 1<=N<=12.

解析

首先可以想到的是每次排序交换的两个块中一定是有序的,那么我们从小到大讨论每一种操作,如果对于第\(i\)种操作,序列每个长度为\(2^{i-1}\)的块都是有序的,那么就看长度为\(2^i\)的块有哪些不是单调递增的。如果不满足要求的块的数量大于2,就无解。否则若数量为1,就交换那一块的两半;数量为2就分4部分两两交换。至于有序的判断,可以用排列的性质,如果块最右边的值减去最左边的值等于块长,说明有序。

另外,对于一个操作序列,任意交换两个元素是没有影响的,所以每找到一个长为\(n\)的操作序列,都要增加\(n!\)中方案。

代码

#include <iostream>
#include <cstdio>
#define N 5000
using namespace std;
int n=1,m,i,a[N];
long long ans,f[N];
int read()
{
char c=getchar();
int w=0;
while(c<'0'||c>'9') c=getchar();
while(c<='9'&&c>='0'){
w=w*10+c-'0';
c=getchar();
}
return w;
}
void dfs(int x,int sum)
{
int gap=(1<<(x-1)),gap1=gap<<1;
for(int i=1;i<=n&&x>1;i+=gap){
if(a[i+gap-1]-a[i]!=gap-1) return;
}
if(x==m+1){
ans+=f[sum];
return;
}
dfs(x+1,sum);
int op[5],cnt=0;
for(int i=1;i<=n;i+=gap1){
int j=(2*i+gap1-1)/2+1;
if(a[i+gap1-1]-a[i]!=gap1-1){
op[++cnt]=i;
op[++cnt]=j;
}
}
if(cnt>4) return;
for(int i=1;i<=cnt;i++){
for(int j=i+1;j<=cnt;j++){
for(int k=0;k<gap;k++) swap(a[op[i]+k],a[op[j]+k]);
dfs(x+1,sum+1);
for(int k=0;k<gap;k++) swap(a[op[i]+k],a[op[j]+k]);
}
}
}
int main()
{
m=read();
for(i=1;i<=m;i++) n*=2;
f[0]=1;
for(i=1;i<=12;i++) f[i]=f[i-1]*i;
for(i=1;i<=n;i++) a[i]=read();
dfs(1,0);
printf("%lld\n",ans);
return 0;
}

[洛谷P3322] SDOI2015 排序的更多相关文章

  1. 洛谷P3324 [SDOI2015]星际战争

    题目:洛谷P3324 [SDOI2015]星际战争 思路: 类似<导弹防御塔>,因为题目保证有解,花费时间小于最终答案时一定无法消灭所有敌人,只要花费时间大于等于最终答案都可以消灭所有敌人 ...

  2. [洛谷P2127] 序列排序

    洛谷题目链接:序列排序 题目描述 小C有一个N个数的整数序列,这个序列的中的数两两不同.小C每次可以交换序列中的任意两个数,代价为这两个数之和.小C希望将整个序列升序排序,问小C需要的最小代价是多少? ...

  3. 题解 P3322 [SDOI2015]排序

    题解 仔细审题,我们会发现 小 \(A\) 认为两个操作序列不同,当且仅当操作个数不同,或者至少一个操作不同(种类不同或者操作位置不同). 所以,对于一种操作,不管是交换哪两段,都算作同一种操作,只会 ...

  4. LOJ #2185 / 洛谷 P3329 - [SDOI2015]约数个数和(莫比乌斯函数)

    LOJ 题面传送门 / 洛谷题面传送门 题意: 求 \(\sum\limits_{i=1}^n\sum\limits_{j=1}^md(ij)\),\(d(x)\) 为 \(x\) 的约数个数. \( ...

  5. 【洛谷P1347】排序

    题目大意:给定 N 个变量和 M 个变量之间的偏序关系,问能否求出这 N 个变量之间的一个全序.若能,输出最少利用多少条已知信息即可求的结果,且输出该全序:若无解,输出到第几条已知信息可以判定无解:若 ...

  6. 洛谷P3809 后缀排序【后缀数组】【模板】

    题目背景 这是一道模板题. 题目描述 读入一个长度为 nn 的由大小写英文字母或数字组成的字符串,请把这个字符串的所有非空后缀按字典序从小到大排序,然后按顺序输出后缀的第一个字符在原串中的位置.位置编 ...

  7. 洛谷P2127 序列排序 [贪心]

    题目传送门 题目描述 小C有一个N个数的整数序列,这个序列的中的数两两不同.小C每次可以交换序列中的任意两个数,代价为这两个数之和.小C希望将整个序列升序排序,问小C需要的最小代价是多少? 输入输出格 ...

  8. [UVA1402]Robotic Sort;[SP2059]CERC07S - Robotic Sort([洛谷P3165][CQOI2014]排序机械臂;[洛谷P4402][Cerc2007]robotic sort 机械排序)

    题目大意:一串数字,使用如下方式排序: 先找到最小的数的位置$P_1$,将区间$[1,P_1]$反转,再找到第二小的数的位置$P_2$,将区间$[2,P_2]$反转,知道排序完成.输出每次操作的$P_ ...

  9. 洛谷——P1327 数列排序

    P1327 数列排序 题目描述 给定一个数列{an},这个数列满足ai≠aj(i≠j),现在要求你把这个数列从小到大排序,每次允许你交换其中任意一对数,请问最少需要几次交换? 输入输出格式 输入格式: ...

随机推荐

  1. 修改Windows 2008以后系统的NTP服务设置

    @echo off echo autor OAK @echo off echo -------------------------------- @echo off echo setup time r ...

  2. elasticsearch索引大小写的问题

    今天用elasticsearch创建索引时碰到一个问题,用大写创建的索引,ES前端插件可以看到用大写创建索引存入的数据 程序启动,搜索的时候,却不显示数据,索引变成了小写,导致数据无法封装传入. 在h ...

  3. python基础学习笔记-切片难点

    numbers = [1,2,3,4,5,6,7,8,9,10] print(numbers[5::-2]) print(numbers[10:5:-2]) print(numbers[:5:-2]) ...

  4. AspNet Core Swagger4.0 生成请求model描述

    今天给大家分享 swagger 俩个冷门的小技巧 获取控制器描述 将 IncludeXmlComments 方法第二个参数设置为 true 即可 public static void IncludeX ...

  5. HTML5 plus 报错 Uncaught SyntaxError: Unexpected identifier at XXXX.html:1

    最近使用 VUE2.X + muse-ui  + HTML5 plus 开发webApp 调用HTML5 plus报错,错误提示如下 Uncaught SyntaxError: Unexpected ...

  6. 交换机安全学习笔记 第五章 DHCP缺陷攻击

    关于DHCP攻击有如下几类攻击方式:   一.耗尽DHCP地址池    通过随机生成源MAC地址,然后伪造DHCPDISCOVER数据包.耗尽DHCP服务器地址池.   免费的攻击工具:  Yersi ...

  7. 2019JAVA第十次实验报告

    Java实验报告 班级 计科二班 学号 20188442 姓名 吴怡君 完成时间 2019.11.15 评分等级 实验代码 package Domon9; import java.awt.Font; ...

  8. N76E003双串口无法进UART1中断问题解决办法

    最近在做有关N76E003的项目,使用到双串口.串口的配置没有特殊要求,最基本的配置 void Uart0_Init(void) { //—————————串口0引脚初始化———————— set_P ...

  9. 干货 | 深入分析 string.intern() 方法

    首先我们来看一段代码: public class InternTest {      public static void main(String[] args) {     String str1 ...

  10. GITFLOW流程

    GITFLOW流程规范 GIT的使用非常的灵活,但是灵活就导致在使用的过程中有各种各样的情况,根据现有项目组的情况,使用GITFLOW流程规范作为项目开发流程规范. 该规范参考地址: 深入理解学习Gi ...