数论+图论+map——cf1323E

/*
首先有gcd的性质
    gcd(a1,a2...) = gcd(a1,a2+a1...)

本题要求所有f(S)的gcd,可以转化成找所有单位点集的gcd
什么是单位点集? 右侧两个点a,b相邻点集想等,则这两个点在同一个集合内
证明:所有不同的f(S)都可以由单位点集的f(S)凑出来 
*/
#include<bits/stdc++.h>
using namespace std;
#define N 500005
#define ll long long 

ll n,m,c[N];
vector<ll>G[N];
map<vector<ll>,ll> mp;

int main(){
    int t;cin>>t;
    while(t--){
        mp.clear(); 
        scanf("%lld%lld",&n,&m);
        for(int i=1;i<=n;i++)scanf("%lld",&c[i]);
        for(int i=1;i<=n;i++)G[i].clear();
        for(int i=1;i<=m;i++){
            int u,v;scanf("%d%d",&u,&v);
            G[v].push_back(u);
        }
        for(int i=1;i<=n;i++)
            sort(G[i].begin(),G[i].end());
        
        for(int i=1;i<=n;i++)
            mp[G[i]]+=c[i];
        
        ll ans=0;
        for(auto p:mp){
            vector<ll> v=p.first;
            if(v.size()==0)continue;
            else ans=__gcd(ans,p.second);
        }
        
        cout<<ans<<'
';
    }    
}
原文地址:https://www.cnblogs.com/zsben991126/p/12455709.html