这题发现了许多有趣的结论,于是可以出很多有趣的题,原题是求对于一个i,j=1.....i-1,gcd(i+j,i-j)=1的个数,但我们转换一蛤可以变成对于一个i , j=1.....i-1,gcd(2i,i+j)=1有多少个,也就是2i 对 a=i+1.....2*i-1这一段区间,有多少个数与2i互质,考虑i为奇数时,由于phi是一个积性函数那么,phi(2*i)=phi(i),而此时的phi(2*i)一定有一半在i+1到2i-1,十分奇妙,如果i为偶数,我们发现phi(2*i)=2*phi(i)怎么证明的我也不太清楚= =,然后一定会有phi(2*i)/2个在i+1到2*i-1之间取到,这也很奇妙= =。
其实比赛的时候,我们前期一直在推gcd(i+j,i-j)=gcd(i-j,2j)=1个个数,此时我们会发现对于新增一个i,我们在计算gcd(i-1,2),gcd(i-2,4),gcd(1,2*(i-1))中互质的个数也就是phi(2i)/2,也就是1 2 3 4 ...a 与 2*a,2*(a-1) ...4 , 2这两个序列中互相取gcd=1的个数也是phi(2*(a+1))/2。
而最后题解中也给出对于每个 i, 求有多少个小于它的 a 满足 gcd(i,a) = 1 且 a 是奇数.
当 i 是奇数时, 答案为phi(i)/2
当 i 是偶数时, 答案为phi(i).
这题我推了一万年规律不知道为撒,队友随便oeis一蛤就出来,而如果我去打表找phi(2*i)和phi(i)之间的规律的话,应该早就找到了吧= =
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int MAXN = 2e7+5;
const int INF = 0x3f3f3f3f;
int cnt;
LL a[MAXN];
int phi[MAXN*2],prime[MAXN*2];
bool is_prime[MAXN*2];
inline void find()
{
phi[1]=1;
for(register int i=2;i<=2*MAXN-1;++i)
{
if(!is_prime[i]){prime[++cnt]=i,phi[i]=i-1;}
int j=1;long long t=2*i;
while(j<=cnt&&t<=MAXN*2-1)
{
is_prime[t]=1;
if(i%prime[j]==0)
{ //欧拉函数公式是phi[i]=i*(1-1/p1)*(1-1/p2)..
phi[t]=phi[i]*prime[j];//质因子相同,只有i不同,且t=prime[j]*i,故作此
break;
}
else phi[t]=phi[i]*(prime[j]-1);//质因子不一样,因为欧拉函数是积性函数,就是
j++;t=1ll*prime[j]*i; //=phi[i]*phi[j]
}
}
}
int main(){
find();
a[0]=0;a[1]=1;a[2]=1;
for(register int i=3;i<=MAXN;++i){
a[i]=phi[2*i]/2;
}
for(register int i=1;i<=MAXN;++i){
a[i]+=a[i-1];
}
int T,n;
scanf("%d",&T);
while(T--){
scanf("%d",&n);
printf("%lld\n",a[n]-1);
}
return 0;
}
/*
*/