对称变量 双哈希

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=5e5+100;

ll mod1=1238532465;
ll mod2=2309412751;
ll mod=1e9+7;
map<pair<ll,ll>,int>mp;
int u[N],v[N],vis[N];
ll h1[N],h2[N];
ll m1[N],m2[N];
int main() {
    int cas;cin>>cas;
    m1[0]=m2[0]=1;
    for(int i=1;i<=N-10;i++) {
        m1[i]=m1[i-1]*1235463%mod1;
        m2[i]=m2[i-1]*1030007%mod2;
    }
    while(cas--) {
        int n,m;
        cin>>n>>m;
        mp.clear();
        for(int i=1;i<=n;i++) vis[i]=0,h1[i]=h2[i]=0;
        for(int i=1;i<=m;i++) {
            scanf("%d%d",&u[i],&v[i]);
            if(u[i]==v[i]) {
                vis[u[i]]=1;
                continue;
            }
            h1[u[i]]=(h1[u[i]]+m1[v[i]])%mod1;
            h2[u[i]]=(h2[u[i]]+m2[v[i]])%mod2;
            h1[v[i]]=(h1[v[i]]+m1[u[i]])%mod1;
            h2[v[i]]=(h2[v[i]]+m2[u[i]])%mod2;
        }

        ll ans=0;
        for(int i=1;i<=n;i++) if(!vis[i]) {
            ans+= mp[{h1[i],h2[i]}] ;
            mp[{h1[i],h2[i]}]++;
        }
        mp.clear();
        for(int i=1;i<=n;i++) if(vis[i]) {
            ans+= mp[{h1[i],h2[i]}] ;
            mp[{h1[i],h2[i]}]++;
        }
        ll a1,a2,b1,b2;
        for(int i=1;i<=m;i++) if(!vis[u[i]]&&!vis[v[i]]||vis[u[i]]&&vis[v[i]]) {
            if(u[i==v[i]) continue;
            a1=(h1[v[i]]-m1[u[i]]+mod1)%mod1;
            b1=(h2[v[i]]-m2[u[i]]+mod2)%mod2;
            a2=(h1[u[i]]-m1[v[i]]+mod1)%mod1;
            b2=(h2[u[i]]-m2[v[i]]+mod2)%mod2;
            if(a1==a2&&b1==b2) ans++;
        }
        cout<<ans<<endl;
    }
}
View Code
原文地址:https://www.cnblogs.com/bxd123/p/12208459.html