[国家集训队]Crash的数字表格 / JZPTAB

题目描述

今天的数学课上,Crash小朋友学习了最小公倍数(Least Common Multiple)。对于两个正整数a和b,LCM(a, b)表示能同时整除a和b的最小正整数。例如,LCM(6, 8) = 24。

回到家后,Crash还在想着课上学的东西,为了研究最小公倍数,他画了一张NM的表格。每个格子里写了一个数字,其中第i行第j列的那个格子里写着数为LCM(i, j)。一个45的表格如下:

1 2 3 4 5
2 2 6 4 10
3 6 3 12 15
4 4 12 4 20
看着这个表格,Crash想到了很多可以思考的问题。不过他最想解决的问题却是一个十分简单的问题:这个表格中所有数的和是多少。当N和M很大时,Crash就束手无策了,因此他找到了聪明的你用程序帮他解决这个问题。由于最终结果可能会很大,Crash只想知道表格里所有数的和mod20101009的值。

输入输出格式

输入格式:

输入的第一行包含两个正整数,分别表示N和M。

输出格式:

输出一个正整数,表示表格中所有数的和mod20101009的值。

输入输出样例

输入样例#1:

4 5

输出样例#1:

122

说明

30%的数据满足N, M≤ 10^3。

70%的数据满足N, M≤ 10^5。

100%的数据满足N, M≤ 10^7。


CTM啥破玩意儿

以上只是一只SB发的牢骚==

这题是反演题

然后我不会做==

首先题目要求的是\(\sum_{i = 1}^{n}\sum_{j=1}^{m}{\frac{i * j}{gcd(i,j)}}\)

先让n < m

然后根据套路先考虑gcd

\(\sum_{d=1}^{n}\sum_{i=1}^{n}\sum_{j=1}^{m{\frac{i * j}{d}[gcd(i , j)== d]}}\)

然后继续根据常规的套路我们再把那个d提出来

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

然后就可以设目标函数\(f(x) = \sum_{i=1}^{n/d}\sum_{j=1}^{m/d}{i * j[gcd(i,j)==x]}\)

然后再设\(g(x) = \sum_{x|t}{f(t)}\)

也就是\(g(x) = \sum_{i=1}^{n/d}\sum_{j=1}^{m/d}{i * j[x|gcd(i,j)]}\)

然后我们把这个x给提出来

\(g(x) = x^2 \sum_{i=1}^{n/dx}\sum_{j=1}^{m/dx}{i * j[1|gcd(i,j)]}\)

然后那个\([1|gcd(i,j)]\)没啥用了

\(g(x)=x^2\sum_{i=1}^{n/dx}\sum_{j=1}^{m/dx}{i*j}\)

然后我们回到我们刚才化简的答案式子

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

是不是可以写成\(\sum_{d=1}{d}f(1)\)

然后我们对\(f(1)\)再反演一下

是不是就能得到\(\sum_{d=1}^{n}{d}\sum_{i=1}^{n}{μ(i)*g(i)}\)

然后我们再把这个\(g(i)\)展开

就得到了\(\sum_{d=1}^{n}{d}\sum_{i=1}^{n}\sum_{x=1}^{n/di}\sum_{y=1}^{m/di}{x*y}\)

然后我们需要预处理出\(\sum_{i=1}^{n}{μ(i)*i^2}\)

后面的那一坨是等差数列可以O(1)计算出来

所以可以两次整除分块O(n)求解

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
# define int long long
const int M = 10000005 ;
const int mod = 20101009 ;
using namespace std ;
inline int read() {
    char c = getchar() ; int x = 0 , w = 1 ;
    while(c>'9'||c<'0') { if(c=='-') w = -1 ; c = getchar() ; }
    while(c>='0'&&c<='9') { x = x*10+c-'0' ; c = getchar() ; }
    return x*w ;
}
int mu[M] , p[M] , pnum ;
bool Notp[M] ;
int sum[M] , n , m ;
int fsum[M] , Ans ;
inline void Get_Mu() {
    Notp[1] = true ; mu[1] = 1 ;
    for(int i = 2 ; i <= n ; i ++) {
        if(!Notp[i]) p[++pnum] = i , mu[i] = -1 ;
        for(int j = 1 ; j <= pnum && i * p[j] <= n ; j ++) {
            Notp[i * p[j]] = true ;
            if(i % p[j] == 0) {
                mu[i * p[j]] = 0 ;
                break ;
            }
            mu[i * p[j]] = -mu[i] ;
        }
    }
    for(int i = 1 ; i <= n ; i ++) sum[i] = (sum[i - 1] + mu[i] + mod)%mod ;
}
inline int Calc(int n , int m) {
    int temp = 0 ;
    for(int l = 1 , r ; l <= n ; l = r + 1) {
        r = min(n / (n / l) , m / (m / l)) ;
        int val = ((1 + n / l) * (n / l) / 2 % mod)%mod * ((1 + m / l) * (m / l) / 2 % mod)%mod ;
        temp = (temp + (fsum[r] - fsum[l - 1] + mod)%mod * val + mod)%mod ;
    }
    return (temp + mod)%mod ;
}
# undef int
int main() {
# define int long long
    n = read() ; m = read() ;
    if(n > m) swap(n , m) ;
    Get_Mu() ;
    for(int i = 1 ; i <= n ; i ++) fsum[i] = (fsum[i - 1] + mu[i] * i * i%mod + mod)%mod ;
    for(int l = 1 , r ; l <= n ; l = r + 1) {
        r = min(n / (n / l) , m / (m / l)) ;
        int val = ((l + r) * (r - l + 1LL) / 2LL + mod)%mod ;
        Ans = (Ans + Calc(n / l , m / l) * val%mod)%mod ;
    }
    printf("%lld\n",Ans) ;
    return 0 ;
}

原文地址:https://www.cnblogs.com/beretty/p/9574775.html

时间: 2024-10-10 15:11:50

[国家集训队]Crash的数字表格 / JZPTAB的相关文章

【题解】[国家集训队]Crash的数字表格 / JZPTAB

求解\(\sum_{i = 1}^{n}\sum_{j = 1}^{m}lcm\left ( i,j \right )\). 有\(lcm\left ( i,j \right )=\frac{ij}{gcd\left ( i,j \right )}\), 所以原本的式子转化为:\(\sum_{i = 1}^{n}\sum_{j = 1}^{m}\frac{ij}{gcd\left ( i,j \right )}\). 注意到\(i, j\) 均为 \(gcd\left ( i,j \right

P1829 [国家集训队]Crash的数字表格 / JZPTAB

推式子太快乐啦!虽然我好蠢而且dummy和maomao好巨(划掉) 思路 莫比乌斯反演的题目 首先这题有\(O(\sqrt n)\)的做法但是我没写咕咕咕 然后就是爆推一波式子 \[ \sum_{i=1}^{n}\sum_{j=1}^{m}lcm(i,j) \] \[ \sum_{i=1}^{n}\sum_{j=1}^{m}\frac{i\times j}{gcd(i,j)} \] 设$ gcd(i,j)=d$ \[ \sum_{d=1}^{n}d\sum_{i=1}^{\lfloor\frac

【[国家集训队]Crash的数字表格 / JZPTAB】

这道题我们要求的是 \[\sum_{i=1}^N\sum_{j=1}^Mlcm(i,j)\] 总所周知\(lcm\)的性质不如\(gcd\)优雅,但是唯一分解定理告诉我们\(gcd(i,j)\times lcm(i,j)=i\times j\) 所以很容易的可以转化成这个柿子 \[\sum_{i=1}^N\sum_{j=1}^M\frac{i\times j}{(i,j)}\] 现在开始套路了 先设两个函数 \[f(n)=\sum_{i=1}^N\sum_{j=1}^M[(i,j)==n]\ti

「luogu1829」 [国家集训队]Crash的数字表格

莫比乌斯反演推柿子,数论分块降复杂度,最后时间复杂度为O(n). 1 #include<bits/stdc++.h> 2 #define ll long long 3 using namespace std; 4 const int N=1e7+10,mod=20101009; 5 int n,m,mi; 6 ll p[N],tot; 7 ll u[N]; 8 bool isp[N]; 9 void getu(int lim){ 10 u[1]=1; 11 for(int i=2;i<=

【莫比乌斯反演】关于Mobius反演与lcm的一些关系与问题简化(BZOJ 2154 crash的数字表格&amp;&amp;BZOJ 2693 jzptab)

BZOJ 2154 crash的数字表格 Description 今天的数学课上,Crash小朋友学习了最小公倍数(Least Common Multiple).对于两个正整数a和b,LCM(a, b)表示能同时被a和b整除的最小正整数.例如,LCM(6, 8) = 24.回到家后,Crash还在想着课上学的东西,为了研究最小公倍数,他画了一张N*M的表格.每个格子里写了一个数字,其中第i行第j列的那个格子里写着数为LCM(i, j).一个4*5的表格如下: 1 2 3 4 5 2 2 6 4

BZOJ 2154: Crash的数字表格 [莫比乌斯反演]

2154: Crash的数字表格 Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 2924  Solved: 1091[Submit][Status][Discuss] Description 今天的数学课上,Crash小朋友学习了最小公倍数(Least Common Multiple).对于两个正整数a和b,LCM(a, b)表示能同时被a和b整除的最小正整数.例如,LCM(6, 8) = 24.回到家后,Crash还在想着课上学的东西,为了研究

【BZOJ 2154】Crash的数字表格 (莫比乌斯+分块)

2154: Crash的数字表格 Description 今天的数学课上,Crash小朋友学习了最小公倍数(Least Common Multiple).对于两个正整数a和b,LCM(a, b)表示能同时被a和b整除的最小正整数.例如,LCM(6, 8) = 24.回到家后,Crash还在想着课上学的东西,为了研究最小公倍数,他画了一张N*M的表格.每个格子里写了一个数字,其中第i行第j列的那个格子里写着数为LCM(i, j).一个4*5的表格如下: 1 2 3 4 5 2 2 6 4 10 3

Crash的数字表格(莫比乌斯反演)

Crash的数字表格 Description 今天的数学课上,Crash小朋友学习了最小公倍数(Least Common Multiple).对于两个正整数a和b,LCM(a, b)表示能同时被a和b整除的最小正整数.例如,LCM(6, 8) = 24.回到家后,Crash还在想着课上学的东西,为了研究最小公倍数,他画了一张NM的表格.每个格子里写了一个数字,其中第i行第j列的那个格子里写着数为LCM(i, j).一个4 5的表格如下: 1 2 3 4 5 2 2 6 4 10 3 6 3 12

Crash的数字表格 BZOJ 2154 / jzptab BZOJ 2693

jzptab [问题描述] 求: 多组询问 [输入格式] 一个正整数T表示数据组数 接下来T行 每行两个正整数 表示N.M [输出格式] T行 每行一个整数 表示第i组数据的结果 [样例输入] 1 4 5 [样例输出] 122 [数据范围] T <= 10000 N, M<=10000000 题解: 即后面那个部分为 H[T],H[T]是积性函数,求详细证明的话将T和d展开为质因数次幂相乘的形式,考虑线性筛中枚举的质数与被筛数的性质即可 1 #include<cmath> 2 #i