码迷,mamicode.com
首页 > 其他好文 > 详细

对称变量 双哈希

时间:2020-01-18 12:34:37      阅读:78      评论:0      收藏:0      [点我收藏+]

标签:pre   i++   span   div   src   nbsp   long   cout   class   

技术图片

 

 

技术图片
#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

对称变量 双哈希

标签:pre   i++   span   div   src   nbsp   long   cout   class   

原文地址:https://www.cnblogs.com/bxd123/p/12208459.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!