解题思路:阶乘逆元+排列数
注意事项:用long long,每乘一个数就取模,避免溢出。
参考代码:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll pow(ll a, int b, int mod) {
ll res = 1;
while (b) {
if (b & 1) res = res * a % mod;
a = a * a % mod;
b >>= 1;
}
return res;
}
int counts[500001]{};
ll inv_fac[500001]{};
ll fac[500001]{};
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
const int mod = 1e9 + 7;
int n;
cin >> n;
int nums[n];
for (int i = 0; i < n; i++) {
int x;
cin >> x;
counts[x]++;
nums[i] = x;
}
n -= 2;
fac[0] = 1;
for (int i = 1; i <= 500000; i++) fac[i] = fac[i - 1] * i % mod;
inv_fac[500000] = pow(fac[500000], mod - 2, mod);
for (int i = 499999; i >= 0; i--) inv_fac[i] = inv_fac[i + 1] * (i + 1) % mod;
ll a = fac[n];
for (int x:counts) if (x >= 2) a = a * inv_fac[x] % mod;
ll ans = 0;
for (int i = 1; i * i <= n; i++) {
if (n % i != 0 || counts[i] == 0) continue;
int j = n / i;
if (counts[j] == 0 || i == j && counts[j] < 2) continue;
if (i == j) ans = (ans + a * fac[counts[i]] % mod * inv_fac[counts[i] - 2] % mod) % mod;
else
ans = (ans + a * fac[counts[i]] % mod * fac[counts[j]] % mod * inv_fac[counts[i] - 1] % mod *
inv_fac[counts[j] - 1] % mod * 2 % mod) % mod;
}
cout << ans << endl;
return 0;
}
0.0分
0 人评分
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程
发表评论 取消回复