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
题意:
求上述公式
思路:
在求解 是否互质
也就
这时我们需要一个规律: ,这样的话我们求满足 对数的时候,只要求 的话 就是求前缀和
证明: 互质 :
先假设
那么
同理可证
注意使用线性求欧拉函数和素数的方法,否则会超时。
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;
}