luogu P3455 [POI2007]ZAP-Queries
Posted gzygzy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了luogu P3455 [POI2007]ZAP-Queries相关的知识,希望对你有一定的参考价值。
luogu P3455 [POI2007]ZAP-Queries
题目让我们求出
以下的n 是 题目中的 a, m 是 b
[sum_{i=1}^{n}sum_{i = 1}^m [gcd(i,j) == d]]
因为有[gcd(i , j) == d]
[gcd(i / d , j / d) == 1]
设(f(k)=sum_{i=1}^nsum_{i=1}^m[gcd(i,j)==k])套用
[sum_{i=1}^nsum_{j=1}^m[gcd(i,j)==d] = sum_{i=1}^{frac nd}sum_{j=1}^{frac md}gcd(i,j)==1]
套用反演公式2
[g(x) = sum_{x|y}f(y)=sum_{x|y}sum_{i=1}^nsum_{i=1}^mgcd(i,j)==y=]
[sum_{i=1}^nsum_{i=1}^msum_{x|gcd(i,j)}=sum_{i=1}^nsum_{i=1}^msum_{x|i,x|j}=[frac nx][frac mx]]
我们求
[f(1) = sum_{1|y}mu(frac y1)g(y)=sum_{y}^{min(n,m)}mu(y)[frac {frac nd}{y}][frac {frac md}{y}]]
可以用前缀和加分块使一次操作达到(O(sqrt n))
所以总复杂度:(O(T sqrt n))
#include <iostream>
#include <cstdio>
#define ll long long
const int maxN = 50000 + 7;
const int N = 50000;
int mu[maxN] , prime[maxN], num;
bool vis[maxN];
void init() {
mu[1] = 1;
for(int i = 2;i <= N;++ i) {
if( !vis[i] ) {
prime[++ num] = i;
mu[i] = -1;
}
for(int j = 1;j <= num && prime[j] * i <= N;++ j) {
vis[prime[j] * i] = true;
if(i % prime[j] == 0) break;
mu[i * prime[j]] = -mu[i];
}
}
for(int i = 1;i <= N;++ i) mu[i] += mu[i - 1];
return ;
}
inline void swap(int &a,int &b) {a ^= b ^= a ^= b;return;}
inline int min(int a,int b) {return a > b ? b : a ;}
int main() {
int T;
scanf("%d",&T);
init();
while(T --) {
int a,b,k;
scanf("%d%d%d",&a,&b,&k);
a /= k;b /= k;
if(a > b) swap(a,b);
long long ans = 0;
for(int l = 1,r;l <= a;l = r + 1) {
r = min(a / (a / l),b / (b / l));
ans += 1LL * ( mu[r] - mu[l - 1] ) * (a / l) * (b / l);
}
printf("%lld
",ans);
}
}
以上是关于luogu P3455 [POI2007]ZAP-Queries的主要内容,如果未能解决你的问题,请参考以下文章
刷题洛谷 P3455 [POI2007]ZAP-Queries
P3455 [POI2007]ZAP-Queries(莫比乌斯反演)
[Luogu3455][POI2007]ZAP-Queries