loj#6229. 这是一道简单的数学题 (??反演+杜教筛)

题意:给定\(n\le 10^9\),求:\(F(n)=\sum_{i=1}^n\sum_{j=1}^i\frac{\mathrm{lcm}(i,j)}{\mathrm{gcd}(i,j)}\),对1e9+7取模

推式子:

\(F(n)=\sum_{i=1}^n\sum_{j=1}^i\frac{\mathrm{lcm}(i,j)}{\mathrm{gcd}(i,j)}\)

\(=\sum_{i=1}^n\sum_{j=1}^i\frac{ij}{\gcd^2(i,j)}\)

\(=\sum_{p=1}^n\frac1{p^2}\sum_{i=1}^n\sum_{j=1}^iij[\gcd(i,j)=p]\)

\(=\sum_{p=1}^n\sum_{i=1}^{n/p}\sum_{j=1}^{i/p}ij[\gcd(i,j)=1]\)

\(=\sum_{p=1}^n\sum_{i=1}^{n/p}i\sum_{j=1}^{i/p}j[\gcd(i,j)=1]\)

根据一个经典式子:\(\sum_{i=1}^ni[\gcd(i,n)=1]=\frac {[n=1]+n\varphi(n)}{2}\)

\(=\sum_{p=1}^n\sum_{i=1}^{n/p}i\frac{[i=1]+i\varphi(i)}{2}\)

\(=\frac {n+\sum_{i=1}^n\lfloor\frac n i\rfloor i^2\varphi(i)}2\)

现在我们考虑求\(\sum_{i=1}^n\lfloor\frac n i\rfloor i^2\varphi(i)\),暴力线性筛是\(O(n)\)的,显然会T,考虑用杜教筛优化

设\(f(i)=i^2\varphi(i),S(n)=\sum_{i=1}^nf(i)\)

原式=\(\sum_{i=1}^n\lfloor\frac n i\rfloor f(i)\)

由于\(\lfloor\frac ni\rfloor\)的取值只有\(O(\sqrt n)\)种,所以可以计算每一块比下一块多多少,然后计算下前缀和

这块可能不太好理解,例如n=11时

ans=11f(1)+5f(2)+3f(3)+2(f(4)+f(5))+1(f(6)+...+f(11)),替换成S则有

ans=(11-5)S(1)+(5-3)S(2)+(3-2)S(3)+(2-1)S(5)+S(11)

直接上杜教筛就行了,因为这些取值在计算S(11)时候都要用到,并且每个n/x只有一种,开个数组记忆化即可

代码里枚举的顺序不太一样,是从S大到S小一样,两块的差就相当于某一块的大小

#include <cstdio>
using namespace std;

const int p = 1000000007, fuck = 1000000;

bool vis[fuck + 233];
int prime[fuck], tot;
int phi[fuck + 233];

int qpow(int x, int y)
{
    int res = 1;
    while (y > 0)
    {
        if (y & 1) res = res * (long long)x % p;
        x = x * (long long)x % p;
        y >>= 1;
    }
    return res;
}

int inv2 = qpow(2, p - 2), inv6 = qpow(6, p - 2);

int s1(int x) { x %= p; return x* (long long)(x + 1) % p * inv2 % p; }
int s2(int x) { x %= p; return x * (long long)(x + 1) % p * (x * 2 + 1) % p * inv6 % p; }
int s3(int x) { return qpow(s1(x), 2); }

bool count[4000010];
int ans[400010], n;

int chuans(int x)
{
    if (x <= fuck) { return phi[x]; }
    if (count[n / x]) return ans[n / x];
    count[n / x] = 1;
    int res = s3(x);
    for (int i = 2, j; i <= x; i = j + 1)
    {
        j = x / (x / i);
        res = ((res - (s2(j) - s2(i - 1)) * (long long)chuans(x / i) % p) % p + p) % p;
    }
    return ans[n / x] = res;
}

int main()
{
    phi[1] = 1;
    for (int i = 2; i <= fuck; i++)
    {
        if (vis[i] == false) prime[++tot] = i, phi[i] = i - 1;
        for (int j = 1; j <= tot && i * prime[j] <= fuck; j++)
        {
            vis[i * prime[j]] = true;
            if (i % prime[j] == 0) { phi[i * prime[j]] = phi[i] * prime[j]; break; }
            else phi[i * prime[j]] = phi[i] * (prime[j] - 1);
        }
        phi[i] = (phi[i - 1] + phi[i] * (long long)i % p * i % p) % p;
    }
    scanf("%d", &n);
    int sum = 0;
    for (int i = 1, j; i <= n; i = j + 1)
    {
        j = n / (n / i);
        sum = (sum + (j - i + 1) * (long long)chuans(n / i) % p) % p;
    }
    sum = (sum + n) % p * (long long)inv2 % p;
    printf("%d\n", sum);
    return 0;
}

Min_25筛表示他需要重复计算根N次,就GG了

原文地址:https://www.cnblogs.com/oier/p/10294169.html

时间: 2024-10-06 00:33:31

loj#6229. 这是一道简单的数学题 (??反演+杜教筛)的相关文章

Loj #6229. 这是一道简单的数学题

几乎是杜教筛版题,自己想了两种做法,一个和φ有关一个和μ有关,当然只写了第一种,,,至于第二种的话参见jzptab的化简(或者crash的数表), 反正φ和μ卷上1都不难,相信你们都会,这里就懒得说了..... 惊喜的发现自己是rank4之后才意识到这个题只有10个人A了.... #include<bits/stdc++.h> #define ll long long #define maxn 1000000 #define ha 1000000007 using namespace std;

EOJ Monthly 2019.11 E. 数学题(莫比乌斯反演+杜教筛+拉格朗日插值)

传送门 题意: 统计\(k\)元组个数\((a_1,a_2,\cdots,a_n),1\leq a_i\leq n\)使得\(gcd(a_1,a_2,\cdots,a_k,n)=1\). 定义\(f(n,k)\)为满足要求的\(k\)元组个数,现在要求出\(\sum_{i=1}^n f(i,k),1\leq n\leq 10^9,1\leq k\leq 1000\). 思路: 首先来化简一下式子,题目要求的就是: \[ \begin{aligned} &\sum_{i=1}^n\sum_{j=1

【Luogu3768】简单的数学题(莫比乌斯反演,杜教筛)

[Luogu3768]简单的数学题(莫比乌斯反演,杜教筛) 题面 洛谷 \[求\sum_{i=1}^n\sum_{j=1}^nijgcd(i,j)\] $ n<=10^9$ 题解 很明显的把\(gcd\)提出来 \[\sum_{d=1}^nd\sum_{i=1}^n\sum_{j=1}^nij[gcd(i,j)==d]\] 习惯性的提出来 \[\sum_{d=1}^nd^3\sum_{i=1}^{n/d}\sum_{j=1}^{n/d}ij[gcd(i,j)==1]\] 后面这玩意很明显的来一发

LOJ 6229 LCM / GCD (杜教筛+Moebius)

链接: https://loj.ac/problem/6229 题意: \[F(n)=\sum_{i=1}^n\sum_{j=1}^i\frac{\mathrm{lcm}(i,j)}{\mathrm{gcd}(i,j)}\] 让你求 \(F(n) \bmod1000000007\). 题解: 设\(\begin{align} f(n)=\sum_{i=1}^n\frac{lcm(i,n)}{gcd(i,n)}&=\sum_{i=1}^n\frac{n*i}{(i,n)^2}\\ &=\su

SCUT - 354 - CC的简单多项式 - 杜教筛

https://scut.online/p/354 跟多项式一点关系都没有. 注意到其实两个多项式在1处求值,那么就是他们的系数加起来. 列一列发现系数就是n以内两两求gcd的值,还自动把0去掉了. 那么就是 \(\sum\limits_{i=1}^{n}\sum\limits_{i=1}^{n}gcd(i^2,j^2)\) 这种情况就要枚举g但是为了方便我们也是枚举g而不是g平方 \(\sum\limits_{g=1}^{n}g^2\sum\limits_{i=1}^{n}\sum\limit

奇怪的数学题(51nod1847)——min_25筛+杜教筛+第二类斯特林数

题面 51nod1847 解析   定义$f(i)$为$i$的次大因数,特别地$f(1)=0$  那么我们就是去求$$\sum_{i=1}^{n}\sum_{j=1}^{n}f^{m}(gcd(i, j))$$ 这种东西的套路就是枚举$gcd$然后用欧拉函数处理, \begin{align*}\sum_{i=1}^{n}\sum_{j=1}^{n}f^{m}(gcd(i, j)) &= \sum_{i=1}^{n}\sum_{j=1}^{\left \lfloor \frac{n}{i}\rig

「洛谷P3768」简单的数学题

题目链接 简单的数学题 题目描述 输入一个整数n和一个整数p,你需要求出 \[\sum_{i=1}^n\sum_{j=1}^n (i\cdot j\cdot gcd(i,j))\ mod\ p\]? 其中\(gcd(a,b)\)表示\(a\)与\(b\)的最大公约数 输入 一行两个整数\(p,n\) 输出 一行一个整数,为题目中所求值 样例 样例输入 998244353 2000 样例输出 883968974 数据范围 \(n\leq 10^{10}\) \(5\times 10^8 \leq

Luogu P3768 简单的数学题

非常恶心的一道数学题,推式子推到吐血. 光是\(\gcd\)求和我还是会的,但是多了个\(ij\)是什么鬼东西. \[\sum_{i=1}^n\sum_{j=1}^nij\gcd(i,j)=\sum_{d=1}^nd\sum_{i=1}^n\sum_{j=1}^nij[\gcd(i,j)=d]\] 很套路的把后面的\(d\)提出来: \[\sum_{d=1}^nd\sum_{i=1}^n\sum_{j=1}^nij[\gcd(i,j)=d]=\sum_{d=1}^nd^3\sum_{i=1}^{

NYOJ 330 一个简单的数学题【数学题】

/* 题目大意:求解1/n; 解题思路:写一个输出小数的算法 关键点:如何处理小数点循环输出 解题人:lingnichong 解题时间:2014-10-18 09:04:22 解题体会:输出小数的算法还没完全理解,先记着 */ 一个简单的数学题 时间限制:3000 ms  |  内存限制:65535 KB 难度:3 描述 zyc最近迷上了数学,一天,dj想出了一道数学题来难住他.算出1/n,但zyc一时答不上来希望大家能编程帮助他. 输入 第一行整数T,表示测试组数.后面T行,每行一个整数 n