[数论] Codeforces 1717E Madoka and The Best University

题目大意

a>0,b>0,c>0,a+b+c=nlcm(c,gcd(a,b))

(3n105)

题解

ans=ablcm(nab,gcd(a,b))=d=1nablcm(nab,d)[gcd(a,b)=d]=d=1nx=1n1dp=1x1lcm(nxd,d)[gcd(p,xp)=1]=d=1nx=1n1dlcm(nxd,d)p=1x1[gcd(p,xp)=1]

f(n)=i=1n1[gcd(i,ni)=1]

f(n)=i=1n1[gcd(i,ni)=1]=i=1n1c|gcd(i,ni)μ(c)=c=1n1μ(c)i=1n1[c|gcd(i,ni)]=c|nμ(c)(nc1)

所以可以在 O(nn) 的时间内求出全体 f(1)f(n)

ans=d=1nx=1n1dlcm(nxd,d)f(x)=x=1nd=1n1xlcm(nxd,d)f(x)=x=1nf(x)d=1n1xlcm(nxd,d)

注意到对于每个 xd 只会枚举到 n1x,所以该式可以 O(nlogn) 求出。

最终时间复杂度 O(nn+nlogn)

Code

#include <bits/stdc++.h>
using namespace std;

#define LL long long

const LL MOD = 1e9 + 7;
const int maxn = 100005;

int mu[maxn];
bool not_prime[maxn];
vector<int> prime;

void get_mu(int len) {
    mu[1] = not_prime[1] = 1;
    for (int i = 2;i <= len;++i) {
        if (!not_prime[i]) { prime.push_back(i); mu[i] = -1; }
        for (auto j : prime) {
            int mid = i * j;
            if (mid > len) break;
            not_prime[mid] = 1;
            if (i % j == 0) { mu[mid] = 0; break; }
            mu[mid] = -mu[i];
        }
    }
}

int f[maxn], g[maxn];

int main() {
    get_mu(100000);
    int n;cin >> n;
    for (int x = 1;x <= n;++x) {
        int c = 1;
        for (c = 1;c * c < x;++c) {
            if (x % c == 0) {
                f[x] += mu[c] * (x / c - 1);
                f[x] += mu[x / c] * (c - 1);
            }
        }
        if (c * c == x) f[x] += mu[c] * (x / c - 1);
    }
    LL ans = 0;
    for (int x = 1;x < n;++x) {
        LL temp = 0;
        for (int d = 1;d <= (n - 1) / x;++d)
            temp = (temp + ((n - x * d) / __gcd(n - x * d, d) * d)) % MOD;
        ans = (ans + temp * f[x] % MOD) % MOD;
    }
    cout << ans << endl;

    return 0;
}
posted @   AE酱  阅读(82)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
历史上的今天:
2020-09-04 [图论分块] HDU 4858 项目管理
点击右上角即可分享
微信分享提示