Codeforces Round #109 (Div. 1) C

题目链接:Double Profiles

题意:给一个无向图,两个顶点 u, v 被称为 “doubles” 当任意 k(k≠u, k≠v) 要么与这两个点都相连,要么都不相连,问有多少对 “double”。

题解:直接 Hash 即可。分两种:第一种为包含自己和相连的顶点;第二种是不包含自己只包含相连的顶点。分别求答案并相加,但是一次 Hash 会 WA,所以就双 Hash 就好了。

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
const LL mod1=1e9+9;
const LL mod2=1e9+7;

LL pow_mod(LL a,LL n,LL mod){
    LL res=1,t=a;
    while(n){
        if(n&1) res=(res*t)%mod;
        t=(t*t)%mod;
        n/=2;
    }
    return res;
}


LL n,m;
LL fun1[1000005],fun2[1000005],u[1000005],v[1000005];

LL Hash_fun(LL x,LL mod){
    return pow_mod(n,x,mod);
}
LL Hash1[1000005],Hash2[1000005];
LL s1[1000005],s2[1000005],cnt1,cnt2;
map<pair<LL,LL> ,LL> mp1,mp2;
LL solve(){
    for(LL i=1;i<=n;i++){
        fun1[i]=fun2[i]=0;
        Hash1[i]=Hash_fun(i,mod1);
        Hash2[i]=Hash_fun(i,mod2);
    }
    for(LL i=1;i<=m;i++){
        fun1[u[i]]=(fun1[u[i]]+Hash1[v[i]])%mod1;
        fun1[v[i]]=(fun1[v[i]]+Hash1[u[i]])%mod1;
        fun2[u[i]]=(fun2[u[i]]+Hash2[v[i]])%mod2;
        fun2[v[i]]=(fun2[v[i]]+Hash2[u[i]])%mod2;
    }
    LL ans=0;
    for(LL i=1;i<=n;i++){
        ans+=mp1[make_pair(fun1[i],fun2[i])]++;
        ans+=mp2[make_pair((fun1[i]+Hash1[i])%mod1,(fun2[i]+Hash2[i])%mod2)]++;
    }

    return ans;
}

int main(){
    scanf("%lld%lld",&n,&m);
    for(LL i=1;i<=m;i++){
        scanf("%lld%lld",&u[i],&v[i]);
    }
    LL ans=solve();
    printf("%lld\n",ans);

    return 0;
}

 

posted on 2019-01-15 19:06  Psong  阅读(88)  评论(0编辑  收藏  举报

导航