HDU5663 Hillan and the girl

Posted henry-1202

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU5663 Hillan and the girl相关的知识,希望对你有一定的参考价值。

题意


[ sum_{i=1}^{n}sum_{j=1}^m[gcd(i,j)为完全平方数] ]

题解

我们设一个函数(f(x))表示
[ f(x)= egin{cases} 1(x为完全平方数)(x不为完全平方数) end{cases} ]
然后大力推式子,最后推出来是这样的
[ sum_{T=1}^{n}frac{n}{T}frac{m}{T}sum_{k|T}mu(frac{T}{k})f(k) ]
后面那段并不是积性函数。。。但是会发现完全平方数其实很少。所以可以枚举完全平方数,大力埃筛(O(sqrt{n}log(sqrt{n})))预处理。复杂度很稳。
然后询问就可以(O(Tsqrt{n}))回答了。

#include <bits/stdc++.h>
using namespace std;

const int N = 1e7 + 10;
#define ll long long
int mu[N], T, p[N], cnt;
ll F[N];
bool vis[N]; 
ll n, m;

void init() {
    mu[1] = 1;
    for(int i = 2; i < N; ++i) {
        if(!vis[i]) p[++cnt] = i, mu[i] = -1;
        for(int j = 1; j <= cnt && i * p[j] < N; ++j) {
            vis[i * p[j]] = 1;
            if(i % p[j] == 0) break;
            mu[i * p[j]] = -mu[i]; 
        }
    }
    for(int i = 1; i * i < N; ++i) 
        for(int j = i * i; j < N; j += i * i) 
            F[j] += mu[j / (i * i)];
    for(int i = 1; i < N; ++i) F[i] += F[i - 1];
}

ll calc(ll n, ll m) {
    ll ans = 0;
    if(n > m) swap(n, m);
    for(ll l = 1, r; l <= n; l = r + 1) {
        r = min(n / (n / l), m / (m / l));
        ans += 1ll * (F[r] - F[l - 1]) * (n / l) * (m / l);
    }
    return ans;
}

int main() {
    init();
    scanf("%d", &T);
    while(T--) {
        scanf("%lld%lld", &n, &m);
        printf("%lld
", 1ll * n * m - calc(n, m));
    }
    return 0;
}

以上是关于HDU5663 Hillan and the girl的主要内容,如果未能解决你的问题,请参考以下文章