好像现在看来这个缩点的思路挺清晰啊

题目描述

有两个非负整数组成的可重集合 $A$ 和 $B$。

现在你可以对 $A$ 中至多 $k$ 个元素进行操作。操作方法为:设你准备操作且未被操作过的 $A$ 中的元素是 $a$,你可以在 $B$ 中选取任意一个元素 $b$,将 $a$ 修改为 $a\oplus b$(这里 $\oplus$ 表示二进制按位异或),然后从 $B$ 中删去 $b$。

最终,你要使 $A$ 中所有元素的 $\mathrm{lowbit}$ 之和最小。正整数的 $\mathrm{lowbit}$ 定义为其二进制最低非零位的值,$0$ 的 $\mathrm{lowbit}$ 规定为 $0$,例如 $\mathrm{lowbit}(0)=0,\mathrm{lowbit}(1)=1,\mathrm{lowbit}(24)=8$。形式化地有:

$\mathrm{lowbit}(x)= \begin{cases} \max(\{2^k:k\in \mathbb{N},2^k|x\}) & x\in \mathbb{N}^+\\ 0 & x=0 \end{cases}$

(其中 $|$ 表示整除)

你需要求出操作后 $A$ 中所有元素的 $\mathrm{lowbit}$ 之和的可能的最小值。

输入格式

第一行一个整数 $n$ 表示 $A$ 的元素个数。
接下来一行 $n$ 个整数 $\{a_i\}$ 表示 $A$ 中元素。
接下来一行一个整数 $m$ 表示 $B$ 的元素个数。
接下来一行 $m$ 个整数 $\{b_i\}$ 表示 $B$ 中元素。
接下来一行一个整数 $k$。

输出格式

输出一行一个整数 $S$ 表示操作后 $A$ 中所有元素的 $\mathrm{lowbit}$ 之和的可能的最小值。

数据范围

对于所有数据,$1\le n,m,k\le 1.2\times 10^6,0\le a_i,b_i\le 10^9$


题目分析

注意到只有两种类型操作是有效的:

  1. $lowbit(a_i) > lowbit(b_i)$
  2. $a_i=b_i$

那么对于$lowbit$相同的点,实际上可以作为等价类考虑。首先预处理出$cnt_{a/b}$表示${{a/b}_i}$中的具有相同lowbit的数目;$cnt_c$表示$a_i$与$b_i$的具有相同lowbit的交。

连边则是在$a_i$和$b_j(j  < i)$间连$(INF,2^{i-1}-2^{j-1})$的边;在$a_i$和$b_i$之间连$(cnt_{ci},2^{i-1})$的边;$S$向$a_i$连$(cnt_{ai},0)$的边;$b_i$向$T'$连$(cnt_{bi},0)$的边;最后$T'$向$T$连$(k,0)$的边限制流量。

由于所求的是最小值,那么对于这张图应该跑最大费用可行流。写的时候没带脑子地直接写了个最大费用最大流

 1 #include<bits/stdc++.h>
 2 typedef long long ll;
 3 const int maxn = 1200035;
 4 const int maxm = 200035;
 5 const int maxNode = 2035;
 6 const ll INF = 2e9;
 7
 8 struct Edge
 9 {
10     int u,v,f,c,dis;
11     Edge(int a=0, int b=0, int c=0, int d=0, int e=0):u(a),v(b),f(c),c(d),dis(e) {}
12 }edges[maxm];
13 int n,m,K,S,T,befT;
14 int edgeTot,head[maxNode],nxt[maxm],bck[maxNode],flw[maxNode];
15 int a[maxn],b[maxn],cnta[35],cntb[35],cntc[35];
16 bool inq[maxNode];
17 ll ans,dis[maxNode];
18
19 int read()
20 {
21     char ch = getchar();
22     int num = 0, fl = 1;
23     for (; !isdigit(ch); ch=getchar())
24         if (ch=='-') fl = -1;
25     for (; isdigit(ch); ch=getchar())
26         num = (num<<1)+(num<<3)+ch-48;
27     return num*fl;
28 }
29 int lowbit(int x)
30 {
31     if (!x) return 0;
32     return log2(x&-x)+1;
33 }
34 void addedge(int u, int v, int c, int dis)
35 {
36     edges[edgeTot] = Edge(u, v, 0, c,  dis), nxt[edgeTot] = head[u], head[u] = edgeTot, ++edgeTot;
37     edges[edgeTot] = Edge(v, u, 0, 0, -dis), nxt[edgeTot] = head[v], head[v] = edgeTot, ++edgeTot;
38 }
39 void maxFlow()
40 {
41     for (;;)
42     {
43         std::queue<int> q;
44         memset(flw, 0, sizeof flw);
45         memset(bck, 0, sizeof bck);
46         memset(dis, -0x3f3f3f3f, sizeof dis);
47         q.push(S), flw[S] = INF, dis[S] = 0;
48         for (int tmp; q.size(); )
49         {
50             tmp = q.front(), q.pop(), inq[tmp] = 0;
51             for (int i=head[tmp]; i!=-1; i=nxt[i])
52             {
53                 int v = edges[i].v;
54                 if (dis[tmp]+edges[i].dis > dis[v]&&edges[i].f < edges[i].c){
55                     bck[v] = i, dis[v] = dis[tmp]+edges[i].dis;
56                     flw[v] = std::min(flw[tmp], edges[i].c-edges[i].f);
57                     if (!inq[v]) inq[v] = 1, q.push(v);
58                 }
59             }
60         }
61         if (dis[T] < 0) return;
62         for (int i=T; i!=S; i=edges[bck[i]].u)
63             edges[bck[i]].f += flw[T], edges[bck[i]^1].f -= flw[T];
64         ans -= dis[T]*flw[T];
65     }
66 }
67 int main()
68 {
69     memset(head, -1, sizeof head);
70     n = read();
71     for (int i=1, val; i<=n; i++)
72         a[i] = read(), val = lowbit(a[i]), ++cnta[val], ans += val?(1ll<<(val-1)):0;
73     m = read();
74     for (int i=1; i<=m; i++)
75         b[i] = read(), ++cntb[lowbit(b[i])];
76     std::sort(a+1, a+n+1);
77     std::sort(b+1, b+m+1);
78     for (int i=1, j=1, p=1, q=1; i<=n; i=j+1)
79     {
80         for (j = i; j!=n&&a[j]==a[j+1]; ++j);
81         for (; p < m&&b[p] < a[i]; ++p);
82         for (q = p; p <= m&&b[p]==a[i]; ++p);
83         cntc[lowbit(a[i])] += std::min(j-i+1, p-q);
84     }
85     K = read(), S = 32*2+10, T = S+1, befT = T+1;
86     addedge(befT, T, K, 0);
87     for (int i=1; i<=31; i++)
88     {
89         addedge(S, i, cnta[i], 0);
90         addedge(i+32, befT, cntb[i], 0);
91         addedge(i, i+32, cntc[i], 1<<(i-1));
92         for (int j=1; j<i; j++)
93             addedge(i, j+32, INF, (1<<(i-1))-(1<<(j-1)));
94     }
95     maxFlow();
96     printf("%lld\n",ans);
97     return 0;
98 }

END

转载于:https://www.cnblogs.com/antiquality/p/10473335.html

【费用流】loj#545. 「LibreOJ β Round #7」小埋与游乐场相关推荐

  1. [费用流] LOJ#545. 「LibreOJ β Round #7」小埋与游乐场

    有两种操作是有效的 lowbit(ai)>lowbit(bj)lowbit(ai)>lowbit(bj)lowbit(a_i)>lowbit(b_j) 或者 ai=bjai=bja_ ...

  2. LibreOJ545. 「LibreOJ β Round #7」小埋与游乐场【网络流】

    545. 「LibreOJ β Round #7」小埋与游乐场 [题目描述] 传送门 [题解] 网络流,我们发现lowbit之后相同的点连出的边是相同的,所以可以缩点. [代码如下] #include ...

  3. [LOJ#522]「LibreOJ β Round #3」绯色 IOI(危机)

    [LOJ#522]「LibreOJ β Round #3」绯色 IOI(危机) 试题描述 IOI 的比赛开始了.Jsp 和 Rlc 坐在一个角落,这时他们听到了一个异样的声音 -- 接着他们发现自己收 ...

  4. [LOJ #521]「LibreOJ β Round #3」绯色 IOI(抵达)(结论)

    #521. 「LibreOJ β Round #3」绯色 IOI(抵达) description solution 因为点的庇护所不能为自身,题目背景在树上,有结论一定是两个相邻点互为庇护所 所以树一 ...

  5. loj #535. 「LibreOJ Round #6」花火 树状数组求逆序对+主席树二维数点+整体二分...

    $ \color{#0066ff}{ 题目描述 }$ 「Hanabi, hanabi--」 一听说祭典上没有烟火,Karen 一脸沮丧. 「有的哦-- 虽然比不上大型烟花就是了.」 还好 Shinob ...

  6. LOJ 572 「LibreOJ Round #11」Misaka Network 与求和——min_25筛

    题目:https://loj.ac/problem/572 莫比乌斯反演得 \( ans=\sum\limits_{D=1}^{n}\left\lfloor\frac{n}{D}\right\rflo ...

  7. LOJ #516. 「LibreOJ β Round #2」DP 一般看规律

    题目描述 给定一个长度为 n 的序列 a,一共有 m 个操作. 每次操作的内容为:给定 x,y,序列中所有 x 会变成 y. 同时我们有一份代码: int ans = 2147483647; for ...

  8. [线段树分治][DP] LOJ #534. 「LibreOJ Round #6」花团

    Solution S o l u t i o n Solution 操作相当于是动态的做一个背包DP. 离线的话,线段树分治一下. 因为结尾是已知的,可以一边分治,得到一个修改操作,就插到线段树. 只 ...

  9. loj 523 「LibreOJ β Round #3」绯色 IOI(悬念) 霍尔定理+基环树+线段树

    题目分析 神仙题(确信) 首先,j−aij-a _ ij−ai​和ai−ja _ i-jai​−j互为相反数,若其中最小值为bib _ ibi​,则一个为bib _ ibi​一个为m−bim-b _ ...

最新文章

  1. XamarinAndroid组件教程RecylerView适配器动画动画种类
  2. python 复制文件夹
  3. 伽卡他卡电子教室 百度百科_创建百度百科的好处
  4. WWISE 交互式音频库
  5. 这100道面试题,用来忽悠半吊子面试官
  6. webgl限制帧率_从《长安十二时辰》到《Science Advances》:大帧数高帧率超表面动态全息显示新方法...
  7. 王爽 汇编语言第三版 第7章 --- 更灵活的定位内存地址的方法(可以理解为 数组形式的内存定位)
  8. 性能测试分析与调优原理
  9. 一文解析Apache Avro数据
  10. 开两个服务内存溢出_应用服务OkHttpClient创建大量对外连接时内存溢出
  11. python连接mysql用哪个模块_pymysql模块使用---Python连接MySQL数据库
  12. 新颖的自我介绍_有哪些非常有创意的自我介绍?
  13. AllJoyn+Android开发案例-android跨设备调用方法
  14. Maven下载及安装
  15. Java数据结构与算法之堆排序
  16. Excel 对比两个表的相同列内容是否一致
  17. learun敏捷框架工作流:企业效率助推神器
  18. android快速复制粘贴,Android开发复制和粘贴
  19. Livid: 消失的未来
  20. 宝塔php缓存关闭,宝塔面板定期释放PHP占用内存

热门文章

  1. 艾伟:MSBuild 简解
  2. SpringBoot项目集成UniPush推送服务
  3. Java-求数字n的所有约数
  4. [Transformer]Segtran:Medical Image Segmentation Using Squeeze-and-Expansion Transformers
  5. Mentor-dft 学习笔记 day13-Scan Insertion for Wrapped Core案例
  6. 荣耀6 H60-L01连接上WIFI但是无法上网
  7. xxtea 加密解密
  8. 名企面试最看中的七点关键能力
  9. 2021暑期学习第23天
  10. FPGA的基础架构,什么是CLB?