超级毒瘤的反演
我们发现这个外层嵌套了所以考虑递归
引理:
在 恒成立
这好理解,假设及时GCD就是较小的,那么值也是i+j
所以递归式为:
不妨:设
稍有常识的OI选手都知道
带入:
枚举GCD
交换枚举顺序
观察右式发现d|n
减少枚举数量
再次发现不需要枚举j
发现时间有三秒而这个是一个调和级数
所以埃式筛就好了
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+100;
const int mod=258280327;
int vis[N];
int Prime[N];
int G[N];
int T[N];
int F[N];
int S[N];
int cnt=0;
void Pre(){
G[1]=1;
for(int i=2;i<N;++i){
if(!vis[i]){
Prime[++cnt]=i;
G[i]=2;
}
for(int j=1;j<=cnt&&Prime[j]*i<N;++j){
vis[i*Prime[j]]=1;
if(i%Prime[j]==0){
G[i*Prime[j]]=G[i];
break;
}
G[i*Prime[j]]=G[i]*2;
}
}
for(int i=1;i<N;++i){
for(int j=i;j<N;j+=i){
T[j]=(T[j]+G[i-1])%mod;
}
}
for(int i=1;i<N;++i){
F[i]=(((F[i-1]+2*i-1-T[i-1])%mod)+mod)%mod;
}
for(int i=1;i<N;++i){
S[i]=(S[i-1]+F[i])%mod;
}
}
int main(){
// freopen("test.in","r",stdin);
Pre();
int T;
scanf("%d",&T);
while(T--){
int x,y;
scanf("%d",&x);
cout<<S[x]<<'\n';
}
}