“21 天好习惯”第一期-12

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

求值:

∑ i = 1 n ∑ j = 1 m l c m ( i , j ) {\sum_{i=1}^{n}\sum_{j=1}^{m}lcm(i,j)} i=1nj=1mlcm(i,j)

易得原式如下:

∑ i = 1 n ∑ j = 1 m i ∗ j g c d ( i , j ) {\sum_{i=1}^{n}\sum_{j=1}^{m}\frac{i*j}{gcd(i,j)}} i=1nj=1mgcd(i,j)ij

枚举最大公因数:

∑ i = 1 n ∑ j = 1 m ∑ d ∣ i , d ∣ j , g c d ( i d , i d ) = 1 i ∗ j d {\sum_{i=1}^{n}\sum_{j=1}^{m}\sum_{d|i,d|j,gcd(\frac{i}{d},\frac{i}{d})=1}\frac{i*j}{d}} i=1nj=1mdi,dj,gcd(di,di)=1dij

非常经典的 g c d {gcd} gcd式子的化法:

∑ d = 1 d ∗ ∑ i = 1 n d ∑ j = 1 m d [ g c d ( i , j ) = 1 ] i ∗ j {\sum_{d=1}d*\sum_{i=1}^{\frac{n}{d}}\sum_{j=1}^{\frac{m}{d}}{[gcd(i,j)=1]i*j}} d=1di=1dnj=1dm[gcd(i,j)=1]ij

式子的后半段出现了互质数对之积之和,考率先单独拿出来,记

s u m ( n , m ) = ∑ i = 1 n ∑ j = 1 m [ g c d ( i , j ) = 1 ] i ∗ j {sum(n,m)=\sum_{i=1}^{n}\sum_{j=1}^{m}[gcd(i,j)=1]i*j} sum(n,m)=i=1nj=1m[gcd(i,j)=1]ij

有:

s u m ( n , m ) = ∑ i = 1 n ∑ j = 1 m ε ( g c d ( i , j ) ) ∗ i ∗ j {sum(n,m)=\sum_{i=1}^{n}\sum_{j=1}^{m}\varepsilon(gcd(i,j))*i*j} sum(n,m)=i=1nj=1mε(gcd(i,j))ij

= ∑ i = 1 n ∑ j = 1 m ∑ d ∣ g c d ( i , j ) μ ( d ) ∗ i ∗ j {=\sum_{i=1}^{n}\sum_{j=1}^{m}\sum_{d|gcd(i,j)}\mu(d)*i*j} =i=1nj=1mdgcd(i,j)μ(d)ij

= ∑ d = 1 μ ( d ) ∗ d 2 ∑ i = 1 n d ∑ j = 1 m d i ∗ j {=\sum_{d=1}\mu(d)*d^2\sum_{i=1}^{\frac{n}{d}}\sum_{j=1}^{\frac{m}{d}}i*j} =d=1μ(d)d2i=1dnj=1dmij

观察上式,前半段可以预处理前缀和;后半段又是一个范围内数对之和,记

g ( n , m ) = ∑ i = 1 n ∑ j = 1 m i ∗ j = n ( n + 1 ) 2 ∗ m ∗ ( m + 1 ) 2 {g(n,m)=\sum_{i=1}^{n}\sum_{j=1}^{m}i*j=\frac{n(n+1)}{2}*\frac{m*(m+1)}{2}} g(n,m)=i=1nj=1mij=2n(n+1)2m(m+1)

可以 o ( 1 ) {o(1)} o(1)求解。

至此:

s u m ( n , m ) = ∑ d = 1 μ ( d ) ∗ d 2 ∗ g ( ⌊ n d ⌋ , ⌊ m d ⌋ ) {sum(n,m)=\sum_{d=1}\mu(d)*d^2*g(⌊\frac{n}{d}⌋,⌊\frac{m}{d}⌋)} sum(n,m)=d=1μ(d)d2g(dn,dm)

我们可以数论分块求解这部分。

回到定义 s u m ( n , m ) {sum(n,m)} sum(n,m)的地方,则原式为:

∑ d = 1 d ∗ s u m ( ⌊ n d ⌋ , ⌊ m d ⌋ ) {\sum_{d=1}d*sum(⌊\frac{n}{d}⌋,⌊\frac{m}{d}⌋)} d=1dsum(dn,dm)

这又是一个可以数论分块求解的式子。

Code:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e7+7,mod=20101009;
int mu[maxn];
ll f[maxn];
int g(ll x,ll y) {
	return (x*(x+1)/2%mod)*(y*(y+1)/2%mod)%mod;
}
int sum(int n,int m) {
	int res(0);
	for(int d=1,x,y,r;d<=n;++d) {
		x=n/d,y=m/d;
    	r=min(n/x,m/y);
    	res=(res+(f[r]-f[d-1])*g(x,y))%mod;
		d=r;
	}
	return res;
}
bool vis[maxn];
vector<int>prime;
inline void init(int n) {
    f[1]=mu[1]=1;
    for(int i=2;i<=n;++i) {
        if(!vis[i]) {
            prime.emplace_back(i); mu[i]=-1;
        }
        for(auto &j:prime) {
            if(i*j>n) break;
            vis[i*j]=1;
            if(i%j==0) break;
            mu[i*j]=-mu[i];
        }
        f[i]=(f[i-1]+(ll)i*i*mu[i])%mod;
    }
}
signed main() {
	cin.sync_with_stdio(false), cin.tie(nullptr),cout.tie(nullptr);
	int n,m;
    cin>>n>>m;
    if(n>m) swap(n,m);//便于处理
	init(n);
    int ans(0);
    for(int d=1,x,y,r;d<=n;++d) {
    	x=n/d,y=m/d;
    	r=min(n/x,m/y);
    	ans=(ans+(ll)(r+d)*(r-d+1)/2*sum(x,y))%mod;
    	d=r;
	}
	cout<<(ans+mod)%mod<<'\n';
	return 0;
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-v4QRI83N-1636734163952)(https://uploadfiles.nowcoder.com/images/20210905/137609403_1630833968576/8748513304B8F3238731469EDE09F8A1 “图片标题”)]

这题线性筛比普通筛快很多。

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值