1 条题解
-
0
自动搬运
来自洛谷,原作者为

Caro23333
Dream Theater 脑残粉搬运于
2025-08-24 22:07:42,当前版本为作者最后更新于2019-08-08 23:32:24,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
思路与Great_Influence相似,更加详细且有代码。
首先观察题目条件。若是最小不整除的正整数,则有:
- 对于任意都有,即
根据这个原理我们进行打表不难发现使得的最大的是,从而对于的,.
将到每一个位置的前缀求出,并且考虑以为转移点的的数量。注意到,所以满足上述两个条件的的数量就是上的倍数的数量减去的倍数的数量。
注意到这些都满足,在预处理之后可以计算出对于每个共有几个满足,从而可以轻易地得到答案。
时间复杂度显然是正确的。
代码:
#include <iostream> #include <cstdlib> #include <cstring> #include <cstdio> #define mod 1000000007 using namespace std; typedef long long ll; const int MAXN = 50; int f[MAXN]; ll n,lcm[MAXN],cnt[10]; inline ll gcd(ll a, ll b) { return b?gcd(b,a%b):a; } inline ll calc(ll l, ll r, ll x) { return r/x-(l-1)/x; } inline ll qpow(ll a, ll b) { ll res = 1; for(; b; a = a*a%mod, b >>= 1ll) if(b&1ll) res = res*a%mod; return res; } int main() { cin >> n; f[2] = 1; for(int i = 3; i<=50; i++) for(int j = 2; j<i; j++) if(i%j) { f[i] = f[j]+1; break; } lcm[1] = 1; int pos = 2; for(pos = 2; pos<=50; pos++) { lcm[pos] = lcm[pos-1]*(pos/gcd(pos,lcm[pos-1])); if(lcm[pos]>n) break; } for(int i = 2; i<=pos; i++) cnt[f[i]+1] += calc(pos+1,n,lcm[i-1])-calc(pos+1,n,lcm[i]); for(int i = 2; i<=pos; i++) cnt[f[i]]++; ll ans = 1; for(int i = 2; i<=5; i++) ans = ans*qpow(i,cnt[i])%mod; cout << ans << endl; return 0; }
- 1
信息
- ID
- 2493
- 时间
- 1000ms
- 内存
- 125MiB
- 难度
- 4
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者