A - 樱花
思路:
- 约数个数 + 线性筛 + 阶乘求质因数的指数
具体实现:
- 变换公式:(思路差不多,盗图一下🤣)
- 如此我们仅需求 ( n ! ) 2 (n!)^{2} (n!)2 的约数个数之和
- 先用线性筛求出所有质因数
- 在用 阶乘求质因数的指数 在 O ( l o g ( n ) ) O(log(n)) O(log(n)) 的时间复杂度求出答案
时间复杂度:
- 预计 O ( n ) 或 O ( n l o g ( n ) ) 但 O ( n n ) 过不去 O(n) 或 O(nlog(n))~但~O(n\sqrt{n})过不去 O(n)或O(nlog(n)) 但 O(nn)过不去
- 实际:小于 O ( n l o g ( n ) ) O(nlog(n)) O(nlog(n))
代码如下:
#include <unordered_map>
#include <unordered_set>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <string>
#include <bitset>
#include <vector>
#include <queue>
#include <cmath>
#include <map>
#include <set>
#define fast ios::sync_with_stdio(false), cin.tie(nullptr); cout.tie(nullptr)
#define mkpr make_pair
#define x first
#define y second
#define int long long
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const LL LL_INF = 0x3f3f3f3f3f3f3f3f;
const double eps = 1e-9;
const int N = 1e6 + 10, M = N * 2;
const int YB = 8, YM = 1e8;
const int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};
int T, cases;
int n, m, times;
int primes[N], cnt;
bool st[N];
void init(int n)
{
for (int i = 2; i <= n; i ++ )
{
if(!st[i]) primes[cnt ++ ] = i;
for (int j = 0; primes[j] <= n / i; j ++ )
{
st[i * primes[j]] = true;
if(i % primes[j] == 0) break;
}
}
}
void solve()
{
cin >> n;
init(n);
int res = 1;
for (int i = 0; i < cnt; i ++ )
{
int p = primes[i];
int s = 0;
// 求 n! 的 质因数p 的指数的简单方法
for (int j = n; j; j /= p) s += j / p;
res = res * (s* 2 + 1) % mod;
}
cout << res << endl;
return;
}
signed main()
{
T = 1;
//fast;cin >> T;
//scanf("%d", &T);
//for (cases = 1; cases <= T; cases ++ )
while(T -- )
solve();
return 0;
}
B - 求正整数
思路:
- 不会写(😥),佬浇浇(😰)