# 【BZOJ2693】jzptab & 【BZOJ2154】Crash的数字表格

## 思路&解法

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

$\sum_{i = 1}^{n}\sum_{j = 1}^{m} \sum_{k = 1}^{min(n, m)}\frac{ij}{k}[gcd(i, j) == k]$

$\sum\limits_{k = 1}^{min(n, m)}{\frac{1}{k}\sum\limits_{i = 1}^{n}\sum\limits_{j = 1}^{m}ij[gcd(i, j) == k]}$

$\sum\limits_{k = 1}^{min(n, m)}{\frac{1}{k}\sum\limits_{i = 1}^{\lfloor{\frac{n}{k}}\rfloor}\sum\limits_{j = 1}^{\lfloor\frac{m}{k}\rfloor}ijk^2[gcd(i, j) == 1]}$

$\sum^{min(n, m)}_{k = 1}k\sum_{i= 1}^{\lfloor{\frac{n}{k}}\rfloor}\sum_{j = 1}^{\lfloor{\frac{m}{k}}\rfloor}ij[gcd(i, j) ==1]$

$\sum_{k}^{min(n, m)} k \sum_{d = 1}^{min(\lfloor {\frac{n}{k}} \rfloor, \lfloor {\frac{m}{k}} \rfloor)}\mu(d) \times \sum_{i|d}\sum_{j|d} ij$

$\sum_{k}^{min(n, m)} k\sum_{d = 1}^{min(\lfloor {\frac{n}{k}} \rfloor, \lfloor {\frac{m}{k}} \rfloor)} \mu(d) \times d^2\sum_{i=1}^{\lfloor{\frac{n}{kd}}\rfloor}\sum_{j=1}^{\lfloor\frac{m}{kd}\rfloor} ij$

$\sum_{k}^{min(n, m)} k\sum_{d = 1}^{min(\lfloor {\frac{n}{k}} \rfloor, \lfloor {\frac{m}{k}} \rfloor)} \mu(d)d^2 F(\lfloor{\frac{n}{kd}}\rfloor, \lfloor{\frac{m}{kd}}\rfloor)$

$\sum_{T=1}^{min(n, m)}{F(\lfloor{\frac{n}{T}}\rfloor, \lfloor{\frac{m}{T}}\rfloor)}\sum_{d|T}\mu(d)d^2{\frac{T}{d}}$

## 代码

【BZOJ2693】jzptab

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

typedef long long LL;

const LL mod = 100000009LL;

const int N = 10000010;

int p[N], total;
bool vis[N];

LL g[N];

void init()
{	g[1] = 1;
for (int i = 2; i <= 10000000; i++)
{	if (!vis[i]) p[++total] = i, g[i] = (LL) (1 - i + mod) % mod;
for (int j = 1; j <= total && i * (LL) p[j] <= 10000000; j++)
{	vis[i * p[j]] = 1;
if (i % p[j] == 0) { g[i * p[j]] = g[i]; break; }
else g[i * p[j]] = (g[i] * g[p[j]]) % mod;
}
}
for (int i = 2; i <= 10000000; i++) g[i] = (g[i] * i + g[i-1]) % mod;
}

LL Get(int n) { return ((LL) n * (LL) (n+1) / 2LL) % mod; }

LL Sum(int n, int m) { return (Get(n) * Get(m)) % mod; }

LL Calc(int n, int m)
{	int last = 0;
LL Ans = 0;
for (int i = 1; i <= min(n, m); i = last+1)
{	last = min(n / (n/i), m / (m/i));
Ans = (Ans + (Sum(n/i, m/i) * (g[last] - g[i-1])) % mod) % mod;
}
return (Ans + mod) % mod;
}

int main()
{	init();
int T;
scanf("%d", &T);
while (T--)
{	int n, m;
scanf("%d %d", &n, &m);
printf("%lld\n", Calc(n, m));
}
return 0;
}


【BZOJ2154】Crash的数字表格

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

typedef long long LL;

const LL mod = 20101009LL;

const int N = 10000010;

int p[N], total;
bool vis[N];

LL g[N];

void init()
{	g[1] = 1;
for (int i = 2; i <= 10000000; i++)
{	if (!vis[i]) p[++total] = i, g[i] = (LL) (1 - i + mod) % mod;
for (int j = 1; j <= total && i * (LL) p[j] <= 10000000; j++)
{	vis[i * p[j]] = 1;
if (i % p[j] == 0) { g[i * p[j]] = g[i]; break; }
else g[i * p[j]] = (g[i] * g[p[j]]) % mod;
}
}
for (int i = 2; i <= 10000000; i++) g[i] = (g[i] * i + g[i-1]) % mod;
}

LL Get(int n) { return ((LL) n * (LL) (n+1) / 2LL) % mod; }

LL Sum(int n, int m) { return (Get(n) * Get(m)) % mod; }

LL Calc(int n, int m)
{	int last = 0;
LL Ans = 0;
for (int i = 1; i <= min(n, m); i = last+1)
{	last = min(n / (n/i), m / (m/i));
Ans = (Ans + (Sum(n/i, m/i) * (g[last] - g[i-1])) % mod) % mod;
}
return (Ans + mod) % mod;
}

int main()
{	init();
int n, m;
scanf("%d %d", &n, &m);
printf("%lld\n", Calc(n, m));
return 0;
}


## 一些其他的东西

posted @ 2018-07-20 21:30  EZ_WYC  阅读(139)  评论(0编辑  收藏  举报