Problem I. Count HDU - 6434
Multiple query, for each n, you need to get
n i-1
∑ ∑ [gcd(i + j, i - j) = 1]
i=1 j=1
Input
On the first line, there is a positive integer T, which describe the number of queries. Next there are T lines, each line give a positive integer n, as mentioned above.
T<=1e5, n<=2e7
Output
Your output should include T lines, for each line, output the answer for the corre- sponding n.
Sample Input
4
978
438
233
666
Sample Output
194041
38951
11065
89963
题意:
求上述公式
思路:
在求解 ans时,首先我们考虑小于n的i,我们要check如题意满足的gcd(a,b)是否为1,也就是a跟bans时,首先我们考虑小于n的i,我们要check如题意满足的gcd(a,b)是否为1,也就是a跟b 是否互质
也就是对于i我们要找满足(a+b=2i)并且(ab互质)的对数,是对于i我们要找满足(a+b=2i)并且(ab互质)的对数,
这时我们需要一个规律:a与b互质,那么a,b分别与(a+b)互质,即a,b与2i互质a与b互质,那么a,b分别与(a+b)互质,即a,b与2i互质,这样的话我们求满足 i条件下的gcd=1i条件下的gcd=1对数的时候,只要求ϕ(2i)2就好了,求ansϕ(2i)2就好了,求ans的话 就是求前缀和
证明:若a与b互质,那么a,b分别与(a+b)若a与b互质,那么a,b分别与(a+b)互质 :
先假设 a与(a+b)不互质,那么令他们的gcd=t,a=t⋅x,(a+b)=t⋅ya与(a+b)不互质,那么令他们的gcd=t,a=t⋅x,(a+b)=t⋅y
那么 b=t⋅y−t⋅x=t⋅(y−x),这样a,b就会有公因子t,矛盾,所以a与(a+b)互质b=t⋅y−t⋅x=t⋅(y−x),这样a,b就会有公因子t,矛盾,所以a与(a+b)互质
同理可证bb
注意使用线性求欧拉函数和素数的方法,否则会超时。
code:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 4e7+7;
const int maxd = 2e7+7;
const int mod = 998244353;
int phi[maxn],prim[maxn];
ll sum[maxn];
void init(){
memset(phi,0,sizeof(phi));
phi[1] = 1;
int id = 0;
for(int i = 2; i < maxn; i++){
if(!phi[i]){
phi[i] = i - 1;
prim[id++] = i;
}
for(int j = 0; j < id && prim[j] * i < maxn; j++){
if(i % prim[j]){
phi[i*prim[j]] = phi[i] * (prim[j] - 1);
}
else{
phi[i*prim[j]] = phi[i] * prim[j];
break;
}
}
}
sum[1] = 0;
for(int i = 2; i < maxd; i++){
sum[i] = phi[i*2] / 2;
sum[i] += sum[i-1];
}
}
int main(){
init();
int t;
scanf("%d",&t);
while(t--){
int n;
scanf("%d",&n);
printf("%lld\n",sum[n]);
}
return 0;
}