题目描述
题目大意:有一个n*m的表格,第i行第j列的数是lcm(i,j),求表格内所有数的和对20101009取模的结果(n,m<=10^7)。
题解
简单的数论题。老套路,先假设 n<=m 。题目要求
∑i=1n∑j=1m[i,j]
画一下柿子
ans=∑i=1n∑j=1mij(i,j)
=∑d=1n∑i=1n∑j=1m[(i,j)=d]ijd
=∑d=1nd∑i=1⌊nd⌋∑j=1⌊md⌋[(i,j)=1]ij
令 F(x,y)=∑xi=1∑yj=1[(i,j=1)]ij ,则
ans=∑d=1ndF(⌊nd⌋,⌊md⌋)
假如我们已经预先求出了 F ,明显这里分块优化一下,维护
但发现好像不能预处理
F
(
我们将
F
反演一下
=∑t=1xt2μ(t)∑i=1⌊xt⌋∑j=1⌊yt⌋ij
我们搞一个新的函数 Sum(x,y)=∑xi=1∑yj=1ij=x(x+1)2y(y+1)2
于是
F(x,y)=∑t=1xt2μ(t)Sum(⌊xt⌋,⌊yt⌋)
我们预处理出
i2μ(i)
的前缀和,再搞一个分块就可以求出
F
了,于是总时间就是
有时候设出函数,分步化简求解比一步算到尽头要更清晰和简单。
对于单组询问,这样做就可以了。如果是多组询问呢?那就需要更秀的操作,这里就不说了,以后有空再去做加强版吧。
代码
#include <bits/stdc++.h>
#define maxn 10000005
#define MOD 20101009
#define temp (i * prime[j])
using namespace std;
int n, m, cnt;
int prime[maxn], miu[maxn], sd[maxn];
bool Vis[maxn];
void Da(){
miu[1] = 1;
for(int i = 2; i <= n; i++){
if(!Vis[i]){
prime[++cnt] = i;
miu[i] = -1;
}
for(int j = 1; j <= cnt && temp <= n; j++){
Vis[temp] = true;
if(i % prime[j] == 0){
miu[temp] = 0;
break;
}
else miu[temp] = -miu[i];
}
}
for(int i = 1; i <= n; i++) miu[i] = 1LL * miu[i] * i * i % MOD;
for(int i = 2; i <= n; i++) miu[i] = (miu[i] + miu[i-1]) % MOD;
for(int i = 1; i <= n; i++) sd[i] = i;
for(int i = 2; i <= n; i++) sd[i] = (sd[i] + sd[i-1]) % MOD;
}
int Sum(int x, int y){
int temp1 = (1LL * x * (x + 1) >> 1) % MOD;
int temp2 = (1LL * y * (y + 1) >> 1) % MOD;
return 1LL * temp1 * temp2 % MOD;
}
int F(int x, int y){
if(x > y) swap(x, y);
int res = 0;
int last;
for(int i = 1; i <= x; i = last+1){
last = min(x/(x/i), y/(y/i));
res = (res + 1LL * (miu[last] - miu[i-1] + MOD) % MOD * Sum(x/i, y/i) % MOD) % MOD;
}
return res;
}
int Solve(){
int ans = 0;
int last;
for(int i = 1; i <= n; i = last+1){
last = min(n/(n/i), m/(m/i));
ans = (ans + 1LL * (sd[last] - sd[i-1] + MOD) % MOD * F(n/i, m/i) % MOD) % MOD;
}
return ans;
}
int main(){
scanf("%d%d", &n, &m);
if(n > m) swap(n, m);
Da();
printf("%d\n", Solve());
return 0;
}//注意乘法可能爆int

本文解析了一道关于求解大规模矩阵中最小公倍数之和的数论问题,通过引入函数进行逐步化简求解,并利用分块优化技术将复杂度降低到线性级别。
&spm=1001.2101.3001.5002&articleId=79723330&d=1&t=3&u=8ed0fe994cda4d29bf7930156ea8bd24)
683

被折叠的 条评论
为什么被折叠?



