考试的时候由于没有想出这道题就弃疗了
发现主要还是自己姿势不够
【问题描述】
(P) 校某宿舍人才辈出,其舍长图书馆男神因被偷拍侧身照而在网络上一票走红。
小鲜肉 (SJY) 是小 (Cat Rainbow) 的好朋友,他也是该宿舍的一员。作为一名著 名的程序设计师,小鲜肉 (SJY) 不但注重萌萌哒的外表,还掌握了无数的黑科技。
有一天,(SJY) 制造了一块比特板,这个比特板有 (2^N)个比特元,编号为 ([0,2^N-1])。 每个比特元有一个饱和值 (T),可以接收一个([0, 2^M-1])之间的整数作为输入信号,并 产生整数 (P) 作为固定的输出信号。当编号为 (i) 的比特元接收到输入信号 (j) 时,将 生成 (W(i,j))枚比特币。
相似的比特元之间还会产生叠加效果。如果两个比特元的编号 (a) 和 (b) 在二进 制下只有一位不同,并且两个比特元中的至少一个接收到的输入信号不小于其饱 和值时,这两个比特元将额外生成 (P_a xor P_b) 枚比特币。
(SJY) 希望给每个比特元适 当的输入信号,使比特板生成的比特币总数尽量多。(SJY) 认为这个问题太简单了, 作为一名小鲜肉,比赚钱更重要的是出去赢得无数妹子的目光,所以他把这个问 题交给你解决。
【输入格式】
从文件 (sjy.in) 中读入数据。 第一行两个整数 (N),(M)。 第二行 (2^N)个整数 (T_i),表示每个比特元的饱和值。 第三行 (2^N)个整数 (P_i),表示每个比特元的固定输出信号。 接下来 (2^N)行每行 $2^M (个整数) W(i,j)$,比特币是虚拟货币,所以 (W(i,j))可能是 负数。
【输出格式】
输出到文件 (sjy.out) 中。 一个整数,表示最多能生成的比特币数。
【数据规模与约定】
对于 (20\%)的数据,(1≤n≤3), (1≤m≤2)。
对于另外(20\%)的数据,(T_i=0) 或 (2^m)。
对于另外 (20\%)的数据,(m=1)。
对于 (100\%)的数据,(1≤n≤8),(1≤m≤8),(0≤T_i≤2^m), (0≤P_i), (|W(i,j)|≤1024)。
【非常垃圾的题意简述】
一看题意感觉非常麻烦,之后努力分析了一下大概是这个样子
有([0,2^n-1])个机器给每一个机器一个([0,2^m-1])的信号
如果(i)机器得到了(j)信号,那么就会产生(W(i,j))的收益(可能存在(W(i,j<0)))
如果两个机器编号在二进制下只有一位不同的话且至少有一个选择的信号大于某一个给定值的话就会产生一个收益,由于这个收益来源于异或,所以这个收益一定为正
【并不存在的分析】
看到这个数据范围基本上是网络流了
有价值这种东西就基本不可能是最大流了,而且这种价值不会重复计算的问题一般不会是费用流
基本确定算法是最小割了
经过一番思考,我们发现一个机器的信号只可能是两种,一种是大于等于(T_i)的最大值,这样能去产生那个异或值的收益,要么激素hi小于(T_i)的最大值这样并不能产生收益所以要尽量选择大的呀
于是有一个非常简单的套路,就是和原点相连表示不饱和,和汇点相连表示饱和,边的容量就是相应的最大值
但是这个时候两个问题没有解决
-
负边的边权如何解决
-
何如限制使得两个点在同时和原点相连的时候割掉一条边
于是考试的时候就疯狂建模,最后成功自闭
首先第一个问题其实蛮好解决的,因为这个题的话每个点必然会和原点和汇点之一相连,所以我们可以直接给每条边加上一数使得其变为正数,最后在把这些加上去的正数减掉就好了
之后第二个问题好像还是很困难的样子,最大权闭合图好像确实做不到啊
但是发现这个题的限制关系很有特点,就是两个机器二进制下只有一位不同
那也就保证了二进制里(1)的个数只相差了(1),那就一定说明奇偶性是不同的
于是我们可以考虑对所有的机器按照二进制下(1)的个数的奇偶性分组,对于其中的一组我们还是用和(S)相连表示不饱和,和(T)相连表示饱和
但是对于另一组我们令和(S)相连表示饱和,和(T)相连表示不饱和
由于我们的分组保证了我们需要加的限制一定存在于两个不同的分组之间,于是我们现在只需要限制两个点一个和(S)连一个和(T)的时候需要割掉一条边就好了,这个就非常显然了直接把那个异或值当作边权把两个点连起来就好了
就这样解决了
代码就咕咕咕了