異或最小生成樹,這裡採用了一種分治的方法來貪心求解最值:
為什麼這樣是對的:顯然我們分成兩個集合我們可以抵消掉高位的一大堆一樣的東西,這個時候,我們可以保證我們的貪心策略是正確的。
為什麼我們要合併兩個集合:假設左邊集合有n
nn個點,右邊集合有m
mm個點,顯然左邊最多鏈結n−1
n - 1
n−1條邊,右邊最多鏈結m−1
m - 1
m−1條邊,要使這n+m
n + m
n+m個點形成一顆樹,必然我們要從左邊選擇乙個點,右邊乙個點鏈結一條邊,這個時候選點連邊我們就可以貪心求解了。
/*
*/#pragma gcc optimize(2)
#pragma gcc optimize(3)
#include
#define mp make_pair
#define pb push_back
#define endl '\n'
using
namespace std;
typedef
long
long ll;
typedef
unsigned
long
long ull;
typedef pair<
int,
int> pii;
const
double pi =
acos(-
1.0)
;const
double eps =
1e-7
;const
int inf =
0x3f3f3f3f
;inline ll read()
while
(c >=
'0'&& c <=
'9')
return f * x;
}void
print
(ll x)
print
(x /10)
;putchar
(x %10+
48);}
const
int n =
2e5+10;
int trie[n *31]
[2], tot;
int a[n]
, n;
void
insert
(int x)
else}}
intfind
(int x)
else
}return ans;
}ll ans =0;
void
dfs1
(int l,
int r,
int dep)
int temp = int_max;
for(
int i = mid +
1; i <= r; i++
) ans +
= temp;
}// vectorg[n];
// void dfs2(int rt, int fa, int w)
// }
intmain()
// dfs2(1, 0, 0);
sort
(a +
1, a +
1+ n)
;dfs1(1
, n,29)
;printf
("%lld\n"
, ans)
;return0;
}
異或最小生成樹
對於n個點的完全圖,每兩個點之間的距離等於兩點的權值的異或和,求最小生成樹 int n struct xortrie void insert ll x,int id val rt x ll answerpos int rt,int pos,ll x return rt void traceback ...
B Graph(異或最小生成樹)
圖是聯通的,並且加邊的時候要保證環一定是異或值為0,所以我們可以保證從乙個點到另乙個點的路徑異或值是不變的,這個時候就簡單了,不就是乙個異或最小生成樹了嘛。我們只要預處理一下,任選乙個點作為根節點去得到從這個點到其他點的路徑異或值,然後再做一遍異或最小生成樹即可。pragma gcc optimiz...
CF888G XOR MST 最小異或生成樹
cf888g trie上貪心,先左右兩邊連邊,再用一條邊的代價連起左右兩顆樹。因為內部的邊一定比跨兩棵樹的邊權笑,顯然是對的。自己瞎yy的。啟發式合併 include define ll long long using namespace std const int 2e5 7 int n,a ch...