HyperlinkHyperlinkHyperlink

https://www.luogu.com.cn/problem/P3322


DescriptionDescriptionDescription

有一个长度为2n2^n2n的序列,每次你可以选择任意两个长度为2k2^k2k的区间交换,求将序列变成有序的操作方案数

数据范围:n≤12n\leq 12n≤12


SolutionSolutionSolution

显然因为是交换操作,所以答案与操作顺序无瓜

由于操作都是2的进制弄的,我们从这个方面下手

首先我们把原序列拆分成2k2^k2k个小段,若所有小段都是有序的,则我们把相邻的两个小段合并在一起,也就是让k=k+1k=k+1k=k+1,此时没有进行操作

若有一个小段是无序的,则我们尝试让它的前半部分和后半部分交换
若交换后变成有序,则让k=k+1k=k+1k=k+1,此时进行了操作,dep=dep+1dep=dep+1dep=dep+1
否则剪枝

若有两个小段是无序的,则分四种情况,设这两段的编号p,qp,qp,q

  1. ppp的前半段和qqq的前半段交换
  2. ppp的前半段和qqq的后半段交换
  3. ppp的后半段和qqq的前半段交换
  4. ppp的后半段和qqq的后半段交换

若上述四种交换能有一种使得p,qp,qp,q这两段都变得有序,则k=k+1,dep=dep+1k=k+1,dep=dep+1k=k+1,dep=dep+1
否则剪枝

若有三段是无序的,直接剪掉

复杂度的上限是O(224)O(2^{24})O(224),然而实际运行中远远达不到

注意回朔


CodeCodeCode

#include<cstdio>
#include<algorithm>
#define jc puts("ok");
using namespace std;int pw[13]={1},n,A[5050],fac[13]={1},ans;
inline void SWAP(int p,int q,int k)
{for(register int i=0;i<pw[k];i++) swap(A[p+i],A[q+i]);return;
}
inline bool JUDGE(int p,int k)
{for(register int i=1;i<pw[k];i++) if(A[p+i]!=A[p+i-1]+1) return false;return true;
}
inline void dfs(int dep,int k)
{if(k>n) {ans+=fac[dep];return;}int p=0,q=0;for(register int i=1;i<=pw[n];i+=pw[k]){if(!JUDGE(i,k)){if(!p) p=i;else if(!q) q=i;}}if(p+q==0) dfs(dep,k+1);elseif(q==0){SWAP(p,p+pw[k-1],k-1);if(JUDGE(p,k)) dfs(dep+1,k+1);SWAP(p,p+pw[k-1],k-1);}elsefor(register int a=0;a<=pw[k-1];a+=pw[k-1])for(register int b=0;b<=pw[k-1];b+=pw[k-1]){SWAP(p+a,q+b,k-1);if(JUDGE(p,k)&&JUDGE(q,k)) {dfs(dep+1,k+1);SWAP(p+a,q+b,k-1);break;}SWAP(p+a,q+b,k-1);}
}
signed main()
{scanf("%d",&n);for(register int i=1;i<=n;i++) pw[i]=pw[i-1]<<1;for(register int i=1;i<=n;i++) fac[i]=fac[i-1]*i;for(register int i=1;i<=pw[n];i++) scanf("%d",A+i);dfs(0,0);printf("%d",ans);
}

P3322 [SDOI2015]排序相关推荐

  1. BZOJ 3990: [SDOI2015]排序(搜索+剪枝)

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

  2. SDOI2015 排序

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

  3. BZOJ.3990.[SDOI2015]排序(DFS)

    题目链接 操作序列的顺序显然是无关的,所以只需按特定顺序求出一个长度为\(l\)的操作序列,它对答案的贡献为\(l!\). 我们从小到大枚举所有选择.若当前为第\(i\)个,如果有一段长度为\(2^i ...

  4. bzoj3990【SDOI2015】排序

    3990: [SDOI2015]排序 Time Limit: 20 Sec   Memory Limit: 128 MB Submit: 521   Solved: 271 [ Submit][ St ...

  5. [暑假的bzoj刷水记录]

    (这篇我就不信有网站来扣) 这个暑假打算刷刷题啥的 但是写博客好累啊  堆一起算了 隔一段更新一下.  7月27号之前刷的的就不写了 , 写的累 代码不贴了,可以找我要啊.. 2017.8.27upd ...

  6. ZJOI2017 讲课Day1笔记

    额,参考一下大神的笔记.... 地址 http://www.cnblogs.com/ARZhu-NOIpAK/p/6596879.html Day1 2017-3-24 3:34:43 苟-- 富贵 ...

  7. 退役前的做题记录1.0

    退役前的做题记录1.0 租酥雨最近很懒qwq,具体表现在写题的时候不想发题解了. 但是想想这样也不太好,就决定发个一句话(半句话到几句话不等)题解上来. 2018-09.18-2018-09.28 [ ...

  8. 数据库中自定义排序规则,Mysql中自定义字段排序规则,Oracle中自定义字段排序规则,decode函数的用法,field函数的用法

    数据库中自定义排序 场景:有一张banner表,表中有一个status字段,有0, 1, 2三个状态位,我想要 1,0,2的自定义排序(这里是重点),然后再进行之上对sequence字段进行二次排序( ...

  9. 伍六七带你学算法 进阶篇-排序算法

    给定一个整数数组 nums,将该数组升序排列. 示例 1: 输入:[5,2,3,1] 输出:[1,2,3,5] 示例 2: 输入:[5,1,1,2,0,0] 输出:[0,0,1,1,2,5] 各排序算 ...

最新文章

  1. 大名鼎鼎的红黑树,你get了么?2-3树 绝对平衡 右旋转 左旋转 颜色反转
  2. 结对编程 黄金点游戏
  3. 技术部门Leader是不是一定要技术大牛担任?
  4. #绘制圆心_SolidWorks2018 绘制草图轮廓练习
  5. VC各种情况下的窗口句柄的获取
  6. 20210422:力扣第237周周赛题解记录(上)
  7. 电脑可以开机但是黑屏_铅锤哥:十五种电脑开机黑屏的原因与解决思路
  8. 三维点云学习(2)中-Kd-tree (k-dimensional tree)
  9. 文件标准标准IO与文件IO 的区别
  10. 【科普】你所不了解的SWF文件
  11. 杭州/北京内推 | 阿里达摩院招聘视觉生成方向学术实习生(人才计划)
  12. rxbus 源码_RxBus 这个 RxBus 稳如老狗 @codeKK Android开源站
  13. 菜鸟排版 latex + texstudio
  14. 论人工智能真空感应悬浮熔炼航母特种钢
  15. 港科百创| 香港科大-越秀集团百万奖金国际创业大赛·2021年度总决赛系列活动全回顾...
  16. 数据库选型-国产数据库如何满足你的需求
  17. php 基于gbk和 Ascii把汉字转换为拼音
  18. 备忘5:爬取微博热门信息以及所有热门微博评论的用户信息
  19. 使用HTML制作会员注册界面
  20. python在数学方面的应用_Python在小学数学应用中的可行性研究

热门文章

  1. 学习python-day01-13---转自Python分布式爬虫打造搜索引擎Scrapy精讲
  2. Camera ITS当中的test_lens_shading_and_color_uniformity测试
  3. Cubase10自编曲平台,享受音乐带来的快乐!
  4. Composer中的ThingWorx模型定义—建模
  5. C语言中lwr是谁的缩写,C语言中关于字符串的操作(转)
  6. 12个同父异母的孩子都有自闭症,简历造假的捐精者吸引了全球顶级专家
  7. JZYZOJ 1382 光棍组织 状压dp
  8. 春林文件批量改名系统
  9. win7批量修改计算机名,文件批量改名助手
  10. php文件更名,php如何批量给文件改名