首先预处理每个数的因数有哪些,然后分别记录a和b中有几个环。 最后就是两层循环,注意取膜。#include<iostream> #include<stdio.h> #include<algorithm> #include<cmath> #include<cstring> #include<string> #include<string.h> #include<queue> #include<stack> #include<map> #define mod 1000000007 #define INF 0x3f3f3f3f using namespace std; int n,m; const int N = 100000+5; struct node { int num,fa; }a[N],b[N]; struct po { vector<int>v; }po[N]; int va[N],vb[N]; int cira[N],cb[N]; void init() { for(int i = 1; i <= 50000; i++) { for(int j = i; j <= 100000; j+= i) { po[j].v.push_back(i); } } return ; } int main() { init(); int tim = 1; while(~scanf("%d%d",&n,&m)) { for(int i = 0; i < n; i++) scanf("%d",&a[i].num); for(int i = 0; i < m; i++) scanf("%d",&b[i].num); memset(va,0,sizeof(va)); memset(vb,0,sizeof(vb)); for(int i = 0; i < n; i++) { int te = a[i].num; a[te].fa = i; } for(int i = 0; i < m; i++) { int te = b[i].num; b[te].fa = i; } memset(cb,0,sizeof(cb)); memset(cira,0,sizeof(cira)); int cnt = 0; for(int i = 0; i < n; i++) { if(!va[i]) { va[i] = 1; int ff = a[i].fa; int root = i; int sum = 1; while(ff != root) { va[ff] = 1; ff = a[ff].fa; sum ++; } cira[cnt++] = sum; } } for(int i = 0; i < m; i++) { if(!vb[i]) { vb[i] = 1; int ff = b[i].fa; int root = i; int sum = 1; while(ff != root) { vb[ff] = 1; ff = b[ff].fa; sum++; } // cout << sum << endl; cb[sum] += 1; } } long long ans = 1; for(int i = 0; i < cnt; i++) { int nn = cira[i]; long long tem = 0; for(int i = 0; i < po[nn].v.size(); i++) { int j = po[nn].v[i]; tem += cb[j]*j; // cout << j <<" " << tem << endl; } ans = (ans%mod*tem%mod)%mod; } printf("Case #%d: %lld\n",tim++,ans); } }
2017 多校 水题
最新推荐文章于 2017-08-24 21:39:53 发布