@[toc]
题意
,求。
链接:hdu6715
思路
方法一:
打表得出:
进一步按套路优化,提出,令得:
- 首先这个东西是,是一个积性函数,所以可以筛出来。
- 这个东西可以按分别预处理出来,预处理的复杂度和埃式筛一样是,空间复杂度也是。
- 最后上面这个式子就可以求和了。
- HDU数据证明,不预处理第二点更快。。。
方法二:
已知
又因为:
因此:
因为当不为时:
而当为时,自然也是,所以也不会影响下面这个式子:
接下来的步骤和方法一就相同啦。
AC_CODE
#pragma comment(linker, "/STACK:102400000,102400000")
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define fi first
#define se second
#define endl '\n'
#define o2(x) (x)*(x)
#define BASE_MAX 31
#define mk make_pair
#define eb push_back
#define SZ(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
#define clr(a, b) memset((a),(b),sizeof((a)))
#define iis std::ios::sync_with_stdio(false); cin.tie(0)
#define my_unique(x) sort(all(x)),x.erase(unique(all(x)),x.end())
using namespace std;
#pragma optimize("-O3")
typedef long long LL;
typedef unsigned long long uLL;
typedef pair pii;
inline LL read() {
LL x = 0;int f = 0;
char ch = getchar();
while (ch < '0' || ch > '9') f |= (ch == '-'), ch = getchar();
while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
return x = f ? -x : x;
}
inline void write(LL x, bool f) {
if (x == 0) {putchar('0'); if(f)putchar('\n');else putchar(' ');return;}
if (x < 0) {putchar('-');x = -x;}
static char s[23];
int l = 0;
while (x != 0)s[l++] = x % 10 + 48, x /= 10;
while (l)putchar(s[--l]);
if(f)putchar('\n');else putchar(' ');
}
int lowbit(int x) { return x & (-x); }
templateT big(const T &a1, const T &a2) { return a1 > a2 ? a1 : a2; }
templateT sml(const T &a1, const T &a2) { return a1 < a2 ? a1 : a2; }
templateT big(const T &f, const R &...r) { return big(f, big(r...)); }
templateT sml(const T &f, const R &...r) { return sml(f, sml(r...)); }
void debug_out() { cerr << '\n'; }
templatevoid debug_out(const T &f, const R &...r) {cerr << f << " ";debug_out(r...);}
#define debug(...) cerr << "[" << #__VA_ARGS__ << "]: ", debug_out(__VA_ARGS__);
const LL INFLL = 0x3f3f3f3f3f3f3f3fLL;
const int HMOD[] = {1000000009, 1004535809};
const LL BASE[] = {1572872831, 1971536491};
const int mod = 1e9 + 7;
const int MOD = 1e9 + 7;//998244353
const int INF = 0x3f3f3f3f;
const int MXN = 1e6 + 7;
const int MXE = 2e5 + 7;
int n, m;
int noprime[MXN], pp[MXN], pcnt;
int phi[MXN], mu[MXN];
LL pre_mu[MXN], mumu[MXN];
std::vector vs[MXN];
void init_prime() {
noprime[0] = noprime[1] = 1;
mu[1] = 1; phi[1] = 1;mumu[1] = 1;
for(int i = 2; i < MXN; ++i) {
if(!noprime[i]) pp[pcnt++] = i, phi[i] = i-1, mu[i] = -1, mumu[i]=-2;
for(int j = 0; j < pcnt && pp[j] * i < MXN; ++j) {
noprime[pp[j]*i] = 1;
phi[pp[j]*i] = (pp[j]-1)*phi[i];
mu[pp[j]*i] = -mu[i];
mumu[i*pp[j]] = mumu[i]*mumu[pp[j]];
if(i % pp[j] == 0) {
phi[pp[j]*i] = pp[j]*phi[i];
mu[pp[j]*i] = 0;
if((i/pp[j])%pp[j]) mumu[i*pp[j]] = mumu[i/pp[j]];
else mumu[i*pp[j]] = 0;
break;
}
}
}
for(int i = 1, t, s; i < MXN; ++i) {
vs[i].eb(0);
s = 0;
for(int j = i; j < MXN; j += i) {
s += mu[j];
vs[i].eb(s);
}
}
}
int main() {
#ifndef ONLINE_JUDGE
freopen("E://ADpan//in.in", "r", stdin);
// freopen("E://ADpan//out.out", "w", stdout);
#endif
init_prime();
int tim = read();
while(tim --) {
n = read(), m = read();
if(n > m) swap(n, m);
LL ans = 0, tmp1, tmp2;
for(int i = 1; i <= n; ++i) {
tmp1 = vs[i][n/i];
tmp2 = vs[i][m/i];
ans += tmp1 * tmp2 * mumu[i];
}
printf("%lld\n", ans);
}
#ifndef ONLINE_JUDGE
cout << "time cost:" << 1.0 * clock() / CLOCKS_PER_SEC << "ms" << endl;
#endif
return 0;
}