(每日一题)CF1139D Steps to One && 2021年天梯赛 L3-3 可怜的简单题(期望,莫比乌斯反演,杜教筛)

Posted 繁凡さん

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了(每日一题)CF1139D Steps to One && 2021年天梯赛 L3-3 可怜的简单题(期望,莫比乌斯反演,杜教筛)相关的知识,希望对你有一定的参考价值。

整理的算法模板合集: ACM模板

点我看算法全家桶系列!!!

实际上是一个全新的精炼模板整合计划


一周连考三门,人都没了

Weblink

2021年天梯赛 L3-3 可怜的简单题

CF1139D

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 可怜的简单题(期望,莫比乌斯反演,杜教筛)的主要内容,如果未能解决你的问题,请参考以下文章

CF1139D Steps to One 题解莫比乌斯反演枚举DP

CF每日一题系列 —— 415A

「每日一题-10.20」cf 1063C

《LeetCode之每日一题》:30.停在原地的方案数

[ 10.03 ]CF每日一题系列—— 534B贪心

[ 9.12 ]CF每日一题系列—— 960B暴力数组