G Xor MST(異或最小生成樹)

2021-10-08 13:21:09 字數 1827 閱讀 7325

異或最小生成樹,這裡採用了一種分治的方法來貪心求解最值:

為什麼這樣是對的:顯然我們分成兩個集合我們可以抵消掉高位的一大堆一樣的東西,這個時候,我們可以保證我們的貪心策略是正確的。

為什麼我們要合併兩個集合:假設左邊集合有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...