对整个过程构造一张有向图,其中$(x,y)\in E$当且仅当$x$把$y$加入,且边权为$a_{x}$

显然这是一棵外向树森林,并再做如下两个构造:

1.新建一个点$a_{0}=0$,将其向所有入度为0的点连边

2.将所有边变为无向边,且边权修改为$a_{x}+a_{y}$($x$和$y$为两端点)

显然最终得到的是一棵树,并且这棵树能被某个过程得到当且仅当$\forall (x,y)\in E,a_{x}\and a_{y}=0$

另一方面,初始答案即边权和,第一个构造中新增的边边权为0,第二个构造中即每一个点都额外产生了原来入度次贡献,而除了0以外其余点入度均为1(而$a_{0}=0$不需要考虑),那么最终答案即边权和-$\sum_{i=1}^{n}a_{i}$

由于后者固定,问题也即求$E=\{(x,y,a_{x}+a_{y})\mid 0\le x,y\le n$且$a_{x}\and a_{y}=0\}$的最大生成树

考虑Boruvka算法,即维护若干个集合(初始每一个点均作为一个集合),并不断加入所有集合(向集合外)最大的出边,注意到每一次集合数回减小一半,最终轮数即$o(\log n)$

在每一轮中,需要求出该最大出边,不妨对每一个点都求出该最大出边即可

而对于$a_{x}$,即需要求出权值是$U\oplus a_{x}$的子集(其中$U$为全集)中与$x$不在同一个连通块中且权值最大的点,对每一个集合预处理其子集权值最大的和不在同一个连通块中权值次大的即可

关于这个,做一个类似于高维前缀和的操作即可

时间复杂度为$o(n\alpha(n)+m2^{m}\log n)$(其中$m\approx 18$),可以通过

  1. 1 #include<bits/stdc++.h>
  2. 2 using namespace std;
  3. 3 #define N 200005
  4. 4 #define M 18
  5. 5 #define ll long long
  6. 6 #define pii pair<int,int>
  7. 7 #define fi first
  8. 8 #define se second
  9. 9 struct Data{
  10. 10 pii mx,cmx;
  11. 11 }g[1<<M];
  12. 12 int n,a[N],fa[N];
  13. 13 ll ans;
  14. 14 pii f[N];
  15. 15 int find(int k){
  16. 16 if (k==fa[k])return k;
  17. 17 return fa[k]=find(fa[k]);
  18. 18 }
  19. 19 void merge(int x,int y,int z){
  20. 20 x=find(x),y=find(y);
  21. 21 if (x!=y){
  22. 22 fa[x]=y;
  23. 23 ans+=z;
  24. 24 }
  25. 25 }
  26. 26 Data merge(Data x,Data y){
  27. 27 if (x.mx<y.mx)swap(x,y);
  28. 28 if (find(x.mx.se)==find(y.mx.se))swap(y.mx,y.cmx);
  29. 29 x.cmx=max(x.cmx,y.mx);
  30. 30 return x;
  31. 31 }
  32. 32 int main(){
  33. 33 scanf("%d",&n);
  34. 34 for(int i=1;i<=n;i++){
  35. 35 scanf("%d",&a[i]);
  36. 36 ans-=a[i];
  37. 37 }
  38. 38 for(int i=0;i<=n;i++)fa[i]=i;
  39. 39 while (1){
  40. 40 bool flag=0;
  41. 41 for(int i=1;i<=n;i++)
  42. 42 if (find(i)!=find(0)){
  43. 43 flag=1;
  44. 44 break;
  45. 45 }
  46. 46 if (!flag)break;
  47. 47 for(int i=0;i<(1<<M);i++)g[i].mx=g[i].cmx=make_pair(-1,-1);
  48. 48 for(int i=0;i<=n;i++)g[a[i]]=merge(g[a[i]],Data{make_pair(a[i],i),make_pair(-1,-1)});
  49. 49 for(int i=0;i<M;i++)
  50. 50 for(int j=0;j<(1<<M);j++)
  51. 51 if (j&(1<<i))g[j]=merge(g[j],g[j^(1<<i)]);
  52. 52 for(int i=0;i<=n;i++)f[i]=make_pair(-1,-1);
  53. 53 for(int i=0;i<=n;i++){
  54. 54 int pos=(a[i]^((1<<M)-1));
  55. 55 pii o=g[pos].mx;
  56. 56 if (o.fi>=0){
  57. 57 if (find(i)==find(o.se))o=g[pos].cmx;
  58. 58 if (o.fi>=0)f[find(i)]=max(f[find(i)],make_pair(o.fi+a[i],o.se));
  59. 59 }
  60. 60 }
  61. 61 for(int i=0;i<=n;i++)
  62. 62 if (f[i].fi>=0)merge(i,f[i].se,f[i].fi);
  63. 63 }
  64. 64 printf("%lld\n",ans);
  65. 65 return 0;
  66. 66 }

[cf1305G]Kuroni and Antihype的更多相关文章

  1. 2021record

    2021-10-14 P2577 [ZJOI2004]午餐 2021-10-13 CF815C Karen and Supermarket(小小紫题,可笑可笑) P6748 『MdOI R3』Fall ...

  2. Codeforce-Ozon Tech Challenge 2020-D. Kuroni and the Celebration(交互题+DFS)

    After getting AC after 13 Time Limit Exceeded verdicts on a geometry problem, Kuroni went to an Ital ...

  3. Codeforce-Ozon Tech Challenge 2020-C. Kuroni and Impossible Calculation(鸽笼原理)

    To become the king of Codeforces, Kuroni has to solve the following problem. He is given n numbers a ...

  4. Codeforce-Ozon Tech Challenge 2020-B. Kuroni and Simple Strings(贪心)

    B. Kuroni and Simple Strings time limit per test1 second memory limit per test256 megabytes inputsta ...

  5. Codeforce-Ozon Tech Challenge 2020-A. Kuroni and the Gifts

    the i-th necklace has a brightness ai, where all the ai are pairwise distinct (i.e. all ai are diffe ...

  6. cf 1305 E. Kuroni and the Score Distribution

    题目传送门:E. Kuroni and the Score Distribution 题目大意:给n和m,输出n个数,这些数里必须要有m对a[i]+a[j]==a[k]  ( i < j < ...

  7. CF 1305E. Kuroni and the Score Distribution

    题目大意:题目给定两个数n和m(1<=n<=5000,0<=m<=1e9)要求构造一个数列A,A中元素 大于等于1,小于等于1e9且满足严格递增 满足ai+aj=ak的(i,j ...

  8. Kuroni and the Punishment CodeForces - 1305F 随机函数mt19937 + 质因子分解

    题意: 给你n个数,你每次操作可以对一个数加1或者减1,让你求你最少需要操作多少次可以使这n个数的公因子大于1 题解: 正常方法就是枚举质因子(假设质因子为x),然后对于这个数组中的数a[i],让a[ ...

  9. Codeforces 杂题集 2.0

      记录一些没有写在其他随笔中的 Codeforces 杂题, 以 Problemset 题号排序   1326D2 - Prefix-Suffix Palindrome (Hard version) ...

随机推荐

  1. 重新整理 .net core 周边阅读篇————AspNetCoreRateLimit 之规则[二]

    前言 本文和上文息息相关. https://www.cnblogs.com/aoximin/p/15315102.html 是紧接着上文invoke来书写的,那么现在来逐行分析invoke到底干了啥. ...

  2. Linux7安装redis6

    首先下载软件包并解压 cd /opt wget https://download.redis.io/releases/redis-6.2.5.tar.gz tar -zxvf redis-6.2.5. ...

  3. golang引用第三方包的报错:no required module provides package [完美解决]

    关于golang第三方包的引用报错:no required module provides package : go.mod file not found in current directory o ...

  4. 2021.9.12考试总结[NOIP模拟51]

    T1 茅山道术 仔细观察发现对于每个点只考虑它前面第一个与它颜色相同的点即可. 又仔细观察发现对一段区间染色后以这个区间内点为端点的区间不能染色. 于是对区间右端点而言,区间染色的贡献为遍历到区间左端 ...

  5. 关于STM32 (Cortex-M3) 中NVIC的分析

    一.STM32 (Cortex-M3) 中的优先级概念 STM32(Cortex-M3)中有两个优先级的概念:抢占式优先级和响应优先级,也把响应优先级称作"亚优先级"或" ...

  6. ES查询区分大小写

    ES查询区分大小写 ES查询在默认的情况下是不区分大小写的,在5.0版本之后将string类型拆分成两种新的数据类型,text用于全文搜索(模糊搜索),keyword用于关键字搜索(精确搜索). 注意 ...

  7. sort命令的学习与实践

    一.用man sort 查看sort的帮助文档 *sort将文件的每一行作为一个单位,相互比较,比较原则是从首字符向后,依次按ASCII码值进行比较,最后将他们按升序输出. [rocrocket@ro ...

  8. UVM:6.2.3 sequencer 的grab 操作

    转载:UVM:6.2.3 sequencer 的grab 操作_tingtang13的博客-CSDN博客 1.grab 比lock 优先级更高. 2.lock 是插到sequencer 仲裁队列的后面 ...

  9. PCIe知识摘要记录

    摘: 一. 在PCIe的Spec中,并没有特别详细的关于Root Complex的定义,从实际的角度来讲,可以把Root Complex理解为CPU与PCIe总线系统通信的媒介.Endpoint处于P ...

  10. Luogu P1538 迎春舞会之数字舞蹈 | 模拟

    题目链接 大水题,暴力输出,代码应该能看吧...... #include<iostream> #include<cstdio> using namespace std; int ...