Memory

Time Limit: 4000ms
Memory Limit: 262144KB

This problem will be judged on HDU. Original ID: 5076
64-bit integer IO format: %I64d      Java class name: Main

Special Judge
 
Little Bob’s computer has 2n bytes of memory. For convenience, n-bit integers 0 to 2n - 1 are used to index these bytes.

Now he wants to assign a value to each byte of the memory. In this problem, a byte is composed of m bits. Therefore he can only assign 0 to 2m - 1 (inclusive) to a single byte.

Bob has some preferences on which value to be assigned to each byte. For the byte indexed by i, if it is assigned with value j (0 ≤ j < 2m), the preference score for it is wi,j.

In addition, each byte has a threshold value. For two different bytes indexed by a and b, if the following two conditions are satisfied, there will be an additional score (ua xor ub):

1.a and b only have one bit of difference in their binary forms;

2.The assigned value of byte a is not less than its threshold value, or the assigned value of byte b is not less than its threshold value.

The total score of an assignment solution is the sum of the preference scores of all bytes plus the sum of all additional scores.

Bob wants to find an assignment solution with the maximum total score. If there are multiple solutions, you can output any of them.

 

Input

The first line contains an integer T (T ≤ 3), denoting the number of the test cases.

For each test case, the first line contains two integers, n and m(1 ≤ n, m ≤ 8), as mentioned above. The second line contains 2n integers, and the i-th integer is the threshold value for byte i. The threshold values are between 0 and 2m - 1, inclusively. The third line contains 2n integers, and the i-th integer is ui(0 ≤ ui < 1024). The next 2n lines give all preference scores. Each line contains 2m integers, and the j-th integer of the i-th line is wi,j (-1024 ≤ wi,j < 1024).

 

Output

For each test case, output one line consisting of 2n integers between 0 and 2m - 1, and the i-th integer is the value assigned to byte i in the assignment solution with the maximum total score.

 

Sample Input

1
3 2
0 1 1 3 3 0 3 3
4 8 8 7 0 9 2 9
-9 -8 3 2
-9 -6 4 1
-6 -8 -5 3
3 -1 -4 -1
-6 -5 1 10
-10 7 3 -10
-3 -10 -4 -5
-2 -1 -9 1

Sample Output

2 2 3 0 3 1 0 3

Source

 
解题:网络流
  1. 对于每个位置拆成两个点,左边源右边汇。
  2. 如果这个位置的index有奇数个1,左边连小于的w,右边连大于等于的w。
  3. 如果这个位置的index有偶数个1,左边连大于等于的w,右边连小于的w。
  4. 每个位置左边往右边连一条inf的弧,代表这两个点不能都不割。
  5. 对于每组a,b,从奇数的小于连向偶数的小于,ua xor ub。
  6. 为了避免负流量可以把所有w加一个1024,不影响最后结果。
  7. 总之建出来是个二分图。
  8. 最后建完就可以发现其实可以不用拆点,但拆了还是更好理解一些。

最后所有的收益加起来减掉最小割就是最大收益。

据说上面是昂神分析的

 #include <bits/stdc++.h>
using namespace std;
const int INF = ~0U>>;
const int maxn = ;
struct arc {
int to,flow,next;
arc(int x = ,int y = ,int z = -) {
to = x;
flow = y;
next = z;
}
} e[maxn*maxn];
int head[maxn],d[maxn],cur[maxn],tot,S,T;
void add(int u,int v,int flow) {
e[tot] = arc(v,flow,head[u]);
head[u] = tot++;
e[tot] = arc(u,,head[v]);
head[v] = tot++;
}
bool bfs() {
queue<int>q;
memset(d,-,sizeof d);
d[S] = ;
q.push(S);
while(!q.empty()) {
int u = q.front();
q.pop();
for(int i = head[u]; ~i; i = e[i].next) {
if(e[i].flow && d[e[i].to] == -) {
d[e[i].to] = d[u] + ;
q.push(e[i].to);
}
}
}
return d[T] > -;
}
int dfs(int u,int low) {
if(u == T) return low;
int a,tmp = ;
for(int &i = cur[u]; ~i; i = e[i].next) {
if(e[i].flow &&d[e[i].to] == d[u]+&&(a=dfs(e[i].to,min(low,e[i].flow)))) {
e[i].flow -= a;
e[i^].flow += a;
low -= a;
tmp += a;
if(!low) break;
}
}
if(!tmp) d[u] = -;
return tmp;
}
int dinic(int ret = ) {
while(bfs()) {
memcpy(cur,head,sizeof cur);
ret += dfs(S,INF);
}
return ret;
}
int U[maxn],Th[maxn],B[maxn],L[maxn],ans[maxn],Bid[maxn],Lid[maxn];
int main() {
int kase,n,m;
scanf("%d",&kase);
while(kase--) {
scanf("%d%d",&n,&m);
n = (<<n);
m = (<<m);
for(int i = tot = ; i < n; ++i)
scanf("%d",Th + i);
for(int i = ; i < n; ++i)
scanf("%d",U + i);
for(int i = ; i < n; ++i) {
B[i] = L[i] = -;
for(int j = ,w; j < m; ++j) {
scanf("%d",&w);
w += ;
if(j >= Th[i] && B[i] < w) {
B[i] = w;
Bid[i] = j;
} else if(L[i] < w) {
L[i] = w;
Lid[i] = j;
}
}
}
S = n<<;
T = S + ;
memset(head,-,sizeof head);
for(int i = ; i < n; ++i) {
int k = __builtin_popcount(i);
add(i,i + n,INF);
if(k&) {
add(S,i,L[i]);
add(i + n,T,B[i]);
} else {
add(S,i,B[i]);
add(i + n,T,L[i]);
}
for(int j = i + ; j < n; ++j) {
if(__builtin_popcount(i^j) == ) {
if(k&) add(i,j + n,U[i]^U[j]);
else add(j,i + n,U[i]^U[j]);
}
}
}
dinic();
for(int i = ; i < n; ++i) {
if(i) putchar(' ');
if(__builtin_popcount(i)&)
printf("%d",(~d[i])?Lid[i]:Bid[i]);
else printf("%d",(~d[i])?Bid[i]:Lid[i]);
}
putchar('\n');
}
return ;
}

HDU 5076 Memory的更多相关文章

  1. hdu 2871 Memory Control(伸展树splay tree)

    hdu 2871 Memory Control 题意:就是对一个区间的四种操作,NEW x,占据最左边的连续的x个单元,Free x 把x单元所占的连续区间清空 , Get x 把第x次占据的区间输出 ...

  2. hdu 2871 Memory Control(线段树)

    题目链接:hdu 2871 Memory Control 题目大意:模拟一个内存分配机制. Reset:重置,释放全部空间 New x:申请内存为x的空间,输出左地址 Free x:释放地址x所在的内 ...

  3. hdu 2871 Memory Control (区间合并 连续段的起始位置 点所属段的左右端点)

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=2871 题意: 四种操作: 1.Reset  清空所有内存2.New x  分配一个大小为x的内存块返回,返 ...

  4. HDU 2871 Memory Control

    一共4种操作 其中用线段树 区间合并,来维护连续空的长度,和找出那个位置.其他用vector维护即可 #include<cstring> #include<cstdio> #i ...

  5. hdu 5076 最小割灵活运用

    这意味着更复杂的问题,关键的事实被抽象出来:每个点,能够赋予既有的值(挑两个一.需要选择,设定ai,bi). 寻找所有和最大.有条件:如果两个点同时满足: 1,:二进制只是有一个不同之处.  2:中的 ...

  6. ●HDU 2871 Memory Control(Splay)

    ●赘述题目 四种操作: ○Reset:将整个内存序列清空. ○New a:在尽量靠左的位置新建一个长度为a的内存块,并输出改内存块起始位置.(各个内存块即使相邻也不会合并..) ○Free a:将a点 ...

  7. HDU 2871"Memory Control"(线段树区间和并+set.lower_bound)

    传送门 •题意 有 n 个内存单元(编号从1开始): 给出 4 种操作: (1)Reset :表示把所有的内存清空,然后输出 "Reset Now". (2)New x :表示申请 ...

  8. 【NX二次开发】NX内部函数,libugui.dll文件中的内部函数

    本文分为两部分:"带参数的函数"和 "带修饰的函数". 浏览这篇博客前请先阅读: [NX二次开发]NX内部函数,查找内部函数的方法 带参数的函数: bool A ...

  9. hdu 3007 Buried memory 最远点对

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3007 Each person had do something foolish along with ...

随机推荐

  1. 模拟 HDOJ 5095 Linearization of the kernel functions in SVM

    题目传送门 /* 题意:表达式转换 模拟:题目不难,也好理解题意,就是有坑!具体的看测试样例... */ #include <cstdio> #include <algorithm& ...

  2. java容器章节总结

  3. 019 [工具软件]窗体置顶 DeskPins

    DeskPins:Windows下将任何窗体置顶的工具 官方主页:https://efotinis.neocities.org/deskpins/index.html 官方下载的是一个exe安装包,用 ...

  4. [转]VC++中对文件的写入和读取

    本文转自:http://blog.csdn.net/fanghb_1984/article/details/7425705 本文介绍两种方法对文件进行读取和写入操作:1.采用fstream类:2.采用 ...

  5. 外文翻译 《How we decide》被情感愚弄 第三节

    本科论文答辩终于结束啦,一切都要继续回到正轨. 这是第三章章最后一节 书的导言 本章第二节 本章第一节 "信用卡是我的敌人."Herman Palmer这样说到.在平日,Herma ...

  6. 复习-PEP8规范(转)

    PEP8 Python 编码规范 一 代码编排1 缩进.4个空格的缩进(编辑器都可以完成此功能),不使用Tap,更不能混合使用Tap和空格.2 每行最大长度79,换行可以使用反斜杠,最好使用圆括号.换 ...

  7. SqlServer 2008 创建测试数据

    包含要点: 数据库的循环 . insert select 句式   . 随机数(rand()函数).绝对值(abs()函数) ) ) DECLARE @randomvalue float SET @s ...

  8. Node.js Addons翻译(C/C++扩展)

    PS:请先升级Node 6.2.1,Node 升级命令 npm install -g n;n stable.NOde.js扩展是一个通过C/C++编写的动态链接库,并通过Node.js的函数requi ...

  9. axios 两种异步模式,代理模式 和 异步模式

    axios 两种异步模式,代理模式 和 异步模式

  10. easyui实现增删改查

    陈旧的开发模式 美工(ui工程师:出一个项目模型) java工程师:将原有的html转成jsp,动态展示数据 缺点: 客户需要调节前端的展示效果 解决:由美工去重新排版,重新选色. 前后端分离: 前端 ...