最小生成树集合合并
https://ac.nowcoder.com/acm/contest/7079/C
由题可知是最小生成树,先把比L【i】小的连通块建立好,合并集合x,y可得-----》 par[y] = x,ans += siz[x]*siz[y],siz[x] += siz[y];
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
unsigned int SA, SB, SC; int n, m, q, LIM;
const int maxn = 5e5+11;
typedef long long ll;
unsigned int rng61(){
SA ^= SA << 16;
SA ^= SA >> 5;
SA ^= SA << 1;
unsigned int t = SA;
SA = SB;
SB = SC;
SC ^= t ^ SA;
return SC;
}
struct Node{
int x,y,w;
bool operator <(const Node b){
return w < b.w;
}
}que[maxn];
int L[maxn];
void gen(){
scanf("%d%d%d%u%u%u%d", &n, &m, &q, &SA, &SB, &SC, &LIM);
for(int i = 1; i <= m; i++){
que[i].x = rng61() % n + 1;
que[i].y = rng61() % n + 1;
que[i].w = rng61() % LIM;
}
for(int i = 1; i <= q; i++){
L[i] = rng61() % LIM;
}
}
ll par[maxn],siz[maxn];
int find(int x){
if(par[x] == -1) return x;
return par[x] = find(par[x]);
}
int main(){
gen();
for(int i=1;i<=n;i++){
par[i] = -1;
siz[i] = 1;
}
sort(que+1,que+1+m);
sort(L+1,L+1+q);
int j = 1;
ll s = 0;
ll ans = 0;
for(int i=1;i<=q;i++){
for(;j<=m && que[j].w<= L[i];j++){
int x = find(que[j].x);
int y = find(que[j].y);
if(x != y) {
par[x] = y;
s += 1LL*siz[y]*siz[x];
siz[y] += siz[x];
}
}
ans ^= s;
}
cout<<ans<<endl;
return 0;
}
寻找真正的热爱

浙公网安备 33010602011771号