牛客练习赛68 牛牛的无向图 题解(krusal思想)

题目链接

题目大意

要你查询q 次询问,每次询问给出一个 L ,询问\(\sum_{i=1}^n\sum_{j=i+1}^n[d(i,j)<=L]\)。其中 [C] 表示当命题 C 为真的时候为 1 否则为 0。

定义 d(u,v) 表示在无向图中点 u 能到达点 v 的所有路径中权值最小的路径的权值。

求所有答案的异或和

题目思路

这个题目类型应该是一个常见的套路题,然而我又双叒叕没做出来

这个求边的最大最小值的题目就要想到kursal的思想就行了。

实际上就是把所有小于L的所有边都加进去 询问互相可达点对,可以用并查集维护。

那么多组询问就可以都离线下来,把询问和边放在一起排序然后处理就好了。

代码

#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<cstdio>
#include<vector>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<unordered_map>
#define fi first
#define se second
#define debug printf(" I am here\n");
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
const ll INF=0x3f3f3f3f3f3f3f3f;
const int maxn=1e6+5,inf=0x3f3f3f3f,mod=199999;
const double eps=1e-10;
unsigned int SA, SB, SC;
int n, m, q, LIM;
int fa[maxn],sum[maxn],cnt;
struct node{
    int u,v,w,opt;
}e[maxn];
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;
}
void init(){
    for(int i=1;i<=n;i++){
        fa[i]=i;
        sum[i]=1;
    }
}
void gen(){
    scanf("%d%d%d%u%u%u%d", &n, &m, &q, &SA, &SB, &SC, &LIM);
    init();
    for(int i = 1,u,v,w; i <= m; i++){
        u = rng61() % n + 1;
        v = rng61() % n + 1;
        w = rng61() % LIM;
        e[++cnt]={u,v,w,1};
    }
    for(int i = 1,w; i <= q; i++){
         w = rng61() % LIM;
         e[++cnt]={-1,-1,w,2};
    }
}
bool cmp(node a,node b){
    if(a.w!=b.w){
        return a.w<b.w;
    }else{
        return a.opt<b.opt;
    }
}
int findd(int x){
    return x==fa[x]?x:fa[x]=findd(fa[x]);
}
signed main(){
    gen();
    sort(e+1,e+1+cnt,cmp);
    ll temp=0,ans=0;
    for(int i=1;i<=cnt;i++){
        if(e[i].opt==1){
            int x=findd(e[i].u),y=findd(e[i].v);
            if(x==y) continue;
            temp+=1ll*sum[x]*sum[y];
            sum[y]+=sum[x];
            fa[x]=y;
        }else{
            ans=ans^temp;
        }
    }
    printf("%lld\n",ans);
    return 0;
}

posted @ 2020-09-11 08:38  hunxuewangzi  阅读(146)  评论(0编辑  收藏  举报