题目链接

Solution

\(Trie\) 树 + 启发式合并.
考虑到是异或,于是按位贪心.让高位的尽量相同.
然后要计算每棵子树的代价,似乎并没有很好的方法??
于是只能启发式合并.
对于每一个有两个子节点的点;
将 \(siz\) 较小的点中的值放到 \(siz\) 较大的子树中去查询即可.
时间复杂度 \(O(n(logn)^2)\) .

Code

Dark 鸡哥 的代码:

//It is made by Awson on 2018.3.18
#include <bits/stdc++.h>
#define LL long long
using namespace std;
const int N = 200000;
const LL INF = 1e18;int n, a[N+5], A[40]; LL bin[40], ans;
struct Trie {int ch[N*35][2], bit[N*35+5], pos;vector<int>key[N*35];void insert(int t) {int u = 0; key[u].push_back(t);for (int i = 35; i >= 1; i--) {if (ch[u][A[i]] == 0) ch[u][A[i]] = ++pos; u = ch[u][A[i]];t -= bin[i-1]*A[i], key[u].push_back(t), bit[u] = i;}}LL qry(int u, int t) {LL ans = 0;for (int i = 1; i <= bit[u]-1; i++) A[i] = t%2, t /= 2;for (int i = bit[u]-1; i >= 1; i--) {if (ch[u][A[i]] != 0) u = ch[u][A[i]];else u = ch[u][A[i]^1], ans += bin[bit[u]-1];}return ans;}LL query(int o) {if (key[o].size() == 1) return 0;if (ch[o][0]) ans += query(ch[o][0]);if (ch[o][1]) ans += query(ch[o][1]);if (!ch[o][0] || !ch[o][1]) return 0;LL tmp = INF; int flag = 0;if (key[ch[o][0]].size() > key[ch[o][1]].size()) flag = 1;int sz = key[ch[o][flag]].size();for (int i = 0; i < sz; i++) tmp = min(qry(ch[o][flag^1], key[ch[o][flag]][i]), tmp);return tmp+bin[bit[o]-2];}
}T;void work() {scanf("%d", &n); bin[0] = 1; for (int i = 1; i <= 35; i++) bin[i] = (bin[i-1]<<1);for (int i = 1; i <= n; i++) scanf("%d", &a[i]);sort(a+1, a+n+1); n = unique(a+1, a+n+1)-a-1;for (int i = 1; i <= n; i++) {for (int j = 1, t = a[i]; j <= 35; j++) A[j] = t%2, t /= 2; T.insert(a[i]);}ans += T.query(0); printf("%I64d\n", ans);
}
int main() {work(); return 0; }

我的代码(有问题):

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const ll maxn=250008;
const ll inf=1926081737;ll ch[maxn*40][2];
ll n,tot,t[maxn*40];
ll w[maxn],cf[43],ans;
vector <ll>a[maxn];void insert(ll x)
{ll u=0;for(ll i=35;i>=0;i--){ll c=(x>>i)&1;if(!ch[u][c]) ch[u][c]=++tot;a[u].push_back(x);x-=c*cf[i];t[u]=i;u=ch0[u][c];}
}ll query(ll x,ll u)
{ll now=0,nn=t[u];for(ll i=nn;i>=0;i--){ll c=(x>>i)&1;if(ch[u][c]) u=ch[u][c];else u=ch[u][c^1],now+=cf[i];}return now;
}void solve(ll u)
{if(a[u].size()==1) return;for(ll i=0;i<2;i++)if(ch[u][i]) solve(ch[u][i]);if(!ch[u][0]||!ch[u][1]) return;ll lx=ch[u][0],rx=ch[u][1];if(a[lx].size()>a[rx].size())swap(lx,rx);ll now=inf,nn=a[lx].size();for(ll i=0;i<nn;i++)now=min(now,query(a[lx][i],rx));now=(now==inf?0:now);ans+=cf[t[u]]+now;return ;
}int main()
{freopen("a.in","r",stdin);freopen("a.ans","w",stdout);scanf("%lld",&n);cf[0]=1; for(ll i=1;i<=40;i++) cf[i]=cf[i-1]*2;for(ll i=1;i<=n;i++)scanf("%lld",&w[i]);sort(w+1,w+n+1);  n=unique(w+1,w+n+1)-w-1;for(ll i=1;i<=n;i++) insert(w[i]);solve(0);printf("%lld\n",ans);return 0;
}

转载于:https://www.cnblogs.com/Kv-Stalin/p/9588612.html

[CF888G] Xor-mst (Trie 树,最小生成树)相关推荐

  1. HDU4825 Xor Sum —— Trie树

    题目链接:https://vjudge.net/problem/HDU-4825 Xor Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Li ...

  2. 【CF888G】Xor-MST(最小生成树,Trie树)

    [CF888G]Xor-MST(最小生成树,Trie树) 题面 CF 洛谷 题解 利用\(Kruskal\)或者\(Prim\)算法都很不好计算. 然而我们还有一个叫啥来着?\(B\)啥啥的算法,就叫 ...

  3. CodeForces 1616H Keep XOR Low {a^b≤x} / CodeForces gym102331 Bitwise Xor {a^b≥x}(trie树 + 计数)

    文章目录 CodeForces 1616H Keep XOR Low problem solution code CodeForces gym102331 Bitwise Xor problem so ...

  4. 2021牛客暑期多校训练营4 E-Tree Xor(异或+思维+区间交 or Trie树)

    E-Tree Xor 首先不考虑区间限制条件,我们给定其中一个点的权值后,那么其他点的权值也就确定.比如 val1=0\text{val}_1=0val1​=0,即可通过变得限制求出其他点valu\t ...

  5. E. XOR Inverse(Trie贪心)

    E. XOR Inverse(Trie&贪心) 思路:异或Trie+Trie+Trie+贪心. 考虑一个性质:两个数的大小只需比较其最高位. 因此考虑将数的每位从高到低存入字典树,显然一个结点 ...

  6. usaco Cowxor (trie 树)

    没想到trie树还可以用在这上面,厉害厉害. [分析]这是字母树的经典应用.首先因为是求xor的最大值,可以用前缀和计算xor值,然后n^2枚举即可. [cpp] view plaincopy for ...

  7. 【bzoj3261】最大异或和 可持久化Trie树

    题目描述 给定一个非负整数序列 {a},初始长度为 N.        有M个操作,有以下两种操作类型: 1.A x:添加操作,表示在序列末尾添加一个数 x,序列的长度 N+1. 2.Q l r x: ...

  8. P4735 最大异或和(可持久化trie树、求最大区间异或和)

    P4735 最大异或和 我们维护一个前缀异或和:s[i]=a[1]xora[2]xor-a[i−1]xora[i]s[i] = a[1] \ xor\ a[2]\ xor\ - a[i-1] \ xo ...

  9. 0x16.基本数据结构 — Trie树(字典树)+ A C 自 动 机

    目录 用TrieTrieTrie树来处理整数异或问题是真的舒服! 一.TrieTrieTrie树 TrieTrieTrie的基本操作 0.初始化 1.插入 2.检索 二.TrieTrieTrie树例题 ...

  10. BZOJ3261 最大异或和 解题报告(可持久化Trie树)

    本题链接:https://www.lydsy.com/JudgeOnline/problem.php?id=3261 题目描述 给定一个非负整数序列{a},初始长度为N. 有M个操作,有以下两种操作类 ...

最新文章

  1. AJAX 一些常用方法
  2. 程序员心中都有一个江湖,java世界,就是一个江湖!
  3. 英特尔k跟kf区别_i5-9600K和i5-9600KF有什么区别
  4. Python函数的定义和使用
  5. (2)通信中为什么要进行AMC?
  6. c语言线程经常段错误的是,由pthread_create引起的段异常
  7. docker网络--理解linux底层实现机制、docker网络模式
  8. 【心灵鸡汤】谁的青春不迷茫
  9. 设置TOMCAT TITLE 、 内存大小 、jdk路径
  10. 黑苹果声卡id注入对照表_声卡,给苦苦做AppleALC的新人一个提示,试着先原版AppleALC.kext,注入ID驱动试试...
  11. canvas基础学习笔记
  12. Axure 获取焦点
  13. matlab仿真项目心得,Matlab与Simulink系统仿真学习心得
  14. 【Python 数据科学】Numpy和Pandas基础
  15. Android WebView重定向GOBACK问题
  16. 【学习笔记】群论入门
  17. ubuntu如何开放对外端口_ubuntu开放指定端口
  18. 构建多平台Docker镜像
  19. python学习------面向对象的程序设计
  20. 颠覆认知!保研的方法竟然多达13种?

热门文章

  1. python怎么修改默认路径_Python小知识之JupyterLab默认启动路径修改
  2. NYOJ 643 发短信(模拟)
  3. istio sidecar流量接管_istio 常见的 10 个异常
  4. protected的继承方式有什么特点_酿酒:大曲酒有哪些配料方式?有什么特点?
  5. atm机编程java_初识Java,关于一个简单的ATM机的java程序设计
  6. Markdown stackoverflow 增加中划线
  7. 算法:转换二叉查找树为最大值加上当前值的数Convert BST to Greater Tree
  8. iOS 13问题记录
  9. 28 Implement strStr() @Python
  10. 特征的标准化和归一化