题目:

题解:

我们可以发现所有的交换器都是一个位置连接着下一层左侧的排序网络,另一个位置连着另一侧的排序网络。

而下一层是由两个更低阶的排序网络构成的。

两个网络互不干扰。所以我们可以通过第一行和最后一行列出多个2-SAT的约束限制。

所以我们可以在每一次都跑一边2-SAT来决策出最外层的交换器是否开启。

然后我们就可以发现每次2-SAT都一定有解,也就是说不可能出现无解的情况。

用2-SAT保证字典序最小即可。

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
inline void read(int &x){
x=0;static char ch;static bool flag;flag = false;
while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
}
#define rg register int
#define rep(i,a,b) for(rg i=(a);i<=(b);++i)
#define per(i,a,b) for(rg i=(a);i>=(b);--i)
const int maxn = 40010;
struct Node{
int to,next;
}G[maxn<<1];
int head[maxn],cnt;
void add(int u,int v){
G[++cnt].to = v;
G[cnt].next = head[u];
head[u] = cnt;
}
inline void clear_G(){
memset(head,0,sizeof head);
cnt = 0;
}
bool mark[maxn];
int n,sta[maxn],top,m;
inline int rev(int u){
return u^1;
}
#define v G[i].to
bool dfs(int u){
if(mark[u]) return true;
if(mark[u^1]) return false;
mark[u] = true;sta[++top] = u;
for(rg i = head[u];i;i=G[i].next){
if(dfs(v) == false) return false;
}return true;
}
#undef v
inline bool clear(){
top = 0;clear_G();
}
int p[maxn],ws[maxn];
bool ans[128][9010];
inline int get(int x,int m){
return (x >> 1) | ((x&1) << m-1);
}
int a[maxn],b[maxn],c[maxn];bool solve_next;
int main(){
while(1){
clear();read(m);if(m == 0) break;
n = 1 << m;int lim = ((n-1) >> 1)+1;
rep(i,0,n-1) read(p[i]),ws[p[i]] = i,a[i] = i;
for(rg k = m;k > 1; -- k){
memset(mark,false,sizeof mark);
clear_G();
int sz = 1 << k,l = 0,r = 0;
rep(i,0,n-1){
b[i] = a[i];c[i] = p[i];
if((i-l+1) == sz){
r = i;
int mid = l+r >> 1;
rep(j,l,r){
if((get(j-l,k)+l <= mid) != (get(ws[a[j]]-l,k)+l <= mid)){
int x = j >> 1,y = ws[a[j]] >> 1;
add(x<<1,(y+lim)<<1|1);add((y+lim)<<1|1,x<<1);
add(x<<1|1,(y+lim)<<1);add((y+lim)<<1,x<<1|1);
}else{
int x = j >> 1,y = ws[a[j]] >> 1;
add(x<<1,(y+lim)<<1);add((y+lim)<<1,x<<1);
add(x<<1|1,(y+lim)<<1|1);add((y+lim)<<1|1,x<<1|1);
}
}l = i+1;r = 0;
}
}
rep(i,0,n-1){
top = 0;
if(dfs(i<<1) == false){
while(top) mark[sta[top--]] = false;
if(dfs(i<<1|1) == false){
solve_next = true;
break;
}
}if(solve_next) break;
}if(solve_next) break;
l = 0;
rep(i,0,n-1){
if((i - l + 1) == sz){
rep(j,l,i){
int x = j >> 1;
if(mark[x<<1|1]){
ans[m-k][x] = 1;
a[get((j^1)-l,k)+l] = b[j];
}else{
ans[m-k][x] = 0;
a[get(j-l,k)+l] = b[j];
}
x = (j >> 1) + lim;
if(mark[x<<1|1]){
ans[m+k-2][x-lim] = 1;
p[get((j^1)-l,k)+l] = c[j];
}else{
ans[m+k-2][x-lim] = 0;
p[get(j-l,k)+l] = c[j];
}
}l = i+1;
}
}
rep(i,0,n-1) ws[p[i]] = i;
}
if(solve_next){
solve_next = false;
puts("-1");
continue;
}
rep(i,0,n-1){
if(a[i] == p[i] && a[i^1] == p[i^1]) ans[m-1][i>>1] = 0;
else if(a[i] == p[i^1] && a[i^1] == p[i]) ans[m-1][i>>1] = 1;
else {solve_next = true;break;}
}
if(solve_next){puts("-1");continue;}
rep(i,0,2*m-2){
rep(j,0,(n-1)>>1){
printf("%d",ans[i][j]);
}puts("");
}puts("");
}
return 0;
}

loj #6136. 「2017 山东三轮集训 Day4」Left的更多相关文章

  1. loj #6138. 「2017 山东三轮集训 Day4」Right

    题目: 题解: 暴力一波 \(SG\) 函数可以发现这么一个规律: \(p\) 为奇数的时候 : \(SG(n) = n \% 2\) \(p\) 为偶数的时候 : \(SG(n) = n \% (p ...

  2. Loj #6142. 「2017 山东三轮集训 Day6」A

    link: https://loj.ac/problem/6142 推完一波式子之后发现求的是:ΣC(N,i)^2, 其中i是偶数. 然后就可以卢卡斯乱搞了,分奇偶和之前的答案合并就好了233. #i ...

  3. LOJ #6145. 「2017 山东三轮集训 Day7」Easy 点分树+线段树

    这个就比较简单了~ Code: #include <cstdio> #include <algorithm> #define N 100004 #define inf 1000 ...

  4. 「2017 山东三轮集训 Day1」Flair

    模拟赛的题 好神仙啊 题面在这里 之前的Solution很蠢 现在已经update.... 题意 有$ n$个商品价格均为$ 1$,您有$ m$种面值的货币,面值为$ C_1..C_m$ 每种物品你有 ...

  5. 【loj6142】「2017 山东三轮集训 Day6」A 结论题+Lucas定理

    题解: 当奇数 发现答案就是C(n,1)^2+C(n,3)^2+...C(n,n)^2 倒序相加,发现就是C(2n,n) 所以答案就是C(2n,n)/2 当偶数 好像并不会证 打表出来可以得到 2.当 ...

  6. 【loj6145】「2017 山东三轮集训 Day7」Easy 动态点分治+线段树

    题目描述 给你一棵 $n$ 个点的树,边有边权.$m$ 次询问,每次给出 $l$ .$r$ .$x$ ,求 $\text{Min}_{i=l}^r\text{dis}(i,x)$ . $n,m\le ...

  7. 「2017 山东三轮集训 Day7」Easy

    一棵带边权的树,多次询问 $x$ 到编号为 $[l,r]$ 的点最短距离是多少 $n \leq 100000$ sol: 动态点分治,每层重心维护到所有点的距离 查询的时候在管辖这个点的 log 层线 ...

  8. #6145. 「2017 山东三轮集训 Day7」Easy 动态点分治

    \(\color{#0066ff}{题目描述}\) JOHNKRAM 最近在参加 C_SUNSHINE 举办的聚会. C 国一共有 n 座城市,这些城市由 n−1 条无向道路连接.任意两座城市之间有且 ...

  9. 「2017 山东三轮集训 Day7 解题报告

    「2017 山东三轮集训 Day7」Easy 练习一下动态点分 每个点开一个线段树维护子树到它的距离 然后随便查询一下就可以了 注意线段树开大点... Code: #include <cstdi ...

随机推荐

  1. MySQL引擎及选择

    一.MySQL的存储引擎 完整的引擎说明还是看官方文档:http://dev.mysql.com/doc/refman/5.6/en/storage-engines.html 这里介绍一些主要的引擎 ...

  2. Python3,x:如何进行手机APP的数据爬取

    Python3,x:如何进行手机APP的数据爬取 一.简介 平时我们的爬虫多是针对网页的,但是随着手机端APP应用数量的增多,相应的爬取需求也就越来越多,因此手机端APP的数据爬取对于一名爬虫工程师来 ...

  3. 介绍Web项目中用到的几款JS日历日期控件和JS文本编辑框插件

    第一款日历日期控件:layDate 官方网站:http://laydate.layui.com/ 第二款日历日期控件:my97 官方网站:http://www.my97.net/ 第三款 文本编辑器控 ...

  4. h5新特性--- 多媒体元素

    在H5中只有一行代码即可实现在页面中插入视频 <video src="插入的视频的名字" controls></video> 可以指明视频的宽度和高度 &l ...

  5. python3爬虫全国地址信息

    PHP方式写的一团糟所以就用python3重写了一遍,所以因为第二次写了,思路也更清晰了些. 提醒:可能会有502的错误,所以做了异常以及数据库事务处理,暂时没有想到更好的优化方法,所以就先这样吧.待 ...

  6. String创建方式的区别

    String str0 = "abc"; String str1 = new String("abc"); 第一句执行后,会在String pool中创建一个& ...

  7. 《Maven实战》第10章 使用Maven进行测试

    10.2maven-surefire-plugin插件 [生命周期]的[阶段]与[插件]的[目标]绑定 default生命周期的test阶段:使用单元测试框架运行测试 Maven内置绑定:defaul ...

  8. 《Maven实战》第14章 灵活的构建

    面对不同环境的差异能够灵活的构建项目, 操作系统的差异 开发环境.测试环境.产品环境的差异(最常用) 不同客户的差异 Maven中灵活的构建:属性.资源过滤.profile 14.1Maven属性 6 ...

  9. java/kotlin 读取文件、写入文件

    package dh.btb.backend.utils import java.io.*object FileUtil { /** * 创建文件 * @param filePath 文件路径(不要以 ...

  10. Django之ModelForm详解

    前言 这是一个神奇的组件,通过名字我们可以看出来,这个组件的功能就是把model和form组合起来.先来一个简单的例子来看一下这个东西怎么用: 比如我们的数据库中有这样一张学生表,字段有姓名,年龄,爱 ...