(每日一题)CF1139D Steps to One && 2021年天梯赛 L3-3 可怜的简单题(期望,莫比乌斯反演,杜教筛)
Posted 繁凡さん
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了(每日一题)CF1139D Steps to One && 2021年天梯赛 L3-3 可怜的简单题(期望,莫比乌斯反演,杜教筛)相关的知识,希望对你有一定的参考价值。
整理的算法模板合集: ACM模板
实际上是一个全新的精炼模板整合计划
一周连考三门,人都没了
Weblink
Problem
Solution
数据较大,要用快速乘不然会爆 long long
Code
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 21544400 + 7;
#define minus(x, y) (1ll * x - y < 0 ? 1ll * x - y + mod : 1ll * x - y)
#define plus(x, y) (1ll * x + y >= mod ? 1ll * x + y - mod : 1ll * x + y)
ll mod;
int mu[N];
ll smu[N];
bool vis[N];
unordered_map <ll, ll> sum_mu;
int primes[N], cnt;
ll n, m;
ll mul(ll a, ll b) {
if (mod <= 1000000000) return a * b % mod;
else if (mod <= 1000000000000ll) return (((a * (b >> 20) % mod) << 20) + (a * (b & ((1 << 20) - 1)))) % mod;
else {
ll d = (ll)floor(a * (long double)b / mod + 0.5);
ll res = (a * b - d * mod) % mod;
if (res < 0) res += mod;
return res;
}
}
ll qpow(ll a, ll b)
{
if(mod == 1) return 0;
ll res = 1;
a = a % mod;
while(b) {
if(b & 1) res = mul(res, a);
a = mul(a, a);
b >>= 1;
}
return res;
}
ll inv(ll x)
{
return qpow(x, mod - 2);
}
void init(int n)
{
mu[1] = 1, vis[1] = 1;
for(int i = 2; i <= n; ++ i) {
if(vis[i] == 0) {
primes[ ++ cnt] = i;
mu[i] = -1;
}
for(int j = 1; j <= cnt && i * primes[j] <= n; ++ j) {
vis[i * primes[j]] = 1;
if(i % primes[j] == 0) {
mu[i * primes[j]] = 0;
break;
}
mu[i * primes[j]] -= mu[i];
}
}
for(int i = 1; i <= n; ++ i)
smu[i] = plus(smu[i - 1], mu[i]);
return ;
}
inline ll g_sum(ll x)
{
return x;
}
inline ll get_sum_mu(ll x)
{
if(x <= N - 7) return smu[x];
if(sum_mu.find(x) != sum_mu.end()) return sum_mu[x];
ll ans = 1;
for(ll l = 2, r; l <= x; l = r + 1) {
r = x / (x / l);
ll tmp = mul((r - l + 1), get_sum_mu(x / l));
ans = minus(ans, tmp);
}
ans = (ans % mod + mod) % mod;
sum_mu[x] = ans / g_sum(1ll);
return ans / g_sum(1ll);
}
void solve(ll m)
{
ll ans = 1;
for(ll l = 1, r; l <= m; l = r + 1) {
r = m / (m / l);
ll tmp = mul((get_sum_mu(r) - get_sum_mu(l - 1)), mul(m / l, inv(m - m / l)));
ans = minus(ans, tmp);
}
ans = (ans + mod) % mod;
printf("%lld\\n", ans);
return ;
}
signed main()
{
scanf("%lld%lld", &m, &mod);
if(m == 1) return printf("1\\n"), 0;
init(N - 7);
solve(m);
return 0;
}
以上是关于(每日一题)CF1139D Steps to One && 2021年天梯赛 L3-3 可怜的简单题(期望,莫比乌斯反演,杜教筛)的主要内容,如果未能解决你的问题,请参考以下文章