2 ≤ n ≤ 1 0 8 2\le n\le 10^8 2≤n≤108
考试时候一直在想什么杜教筛和分块,但是数组开不下而且好像错了
这个分数裂项简直绝了
考虑记
f n = ∑ 1 ≤ a < b ≤ n g c d ( a , b ) = 1 a + b ≥ n 1 a b f_n=\sum_{\begin{matrix}1\le afn=1≤a<b≤ngcd(a,b)=1a+b≥n∑ab1
考虑递推,那么新增的必定有 b = n b=n b=n 而且还要减去 a + b = n − 1 a+b=n-1 a+b=n−1 的方案
f n = f n − 1 + ∑ 1 ≤ a ≤ n g c d ( a , n ) = 1 1 a n − ∑ 1 ≤ a < b ≤ n − 1 g c d ( a , b ) = 1 a + b = n − 1 1 a b f_n=f_{n-1}+\sum_{\begin{matrix}1\le a\le n\\gcd(a,n)=1\end{matrix}}\frac{1}{an}-\sum_{\begin{matrix}1\le afn=fn−1+1≤a≤ngcd(a,n)=1∑an1−1≤a<b≤n−1gcd(a,b)=1a+b=n−1∑ab1
然后开始操作了…
发现减去的似乎有点搞头,记 g n = ∑ 1 ≤ a < b ≤ n g c d ( a , b ) = 1 a + b = n 1 a b g_n=\sum_{\begin{matrix}1\le agn=1≤a<b≤ngcd(a,b)=1a+b=n∑ab1
有边界 g 2 = 0 g_2=0 g2=0
然后因为 g c d ( a , b ) = g c d ( a , a + b ) = g c d ( a , n ) = g c d ( b , n ) , 1 a b = 1 n ( 1 a + 1 b ) gcd(a,b)=gcd(a,a+b)=gcd(a,n)=gcd(b,n),\frac{1}{ab}=\frac{1}{n}(\frac{1}{a}+\frac{1}{b}) gcd(a,b)=gcd(a,a+b)=gcd(a,n)=gcd(b,n),ab1=n1(a1+b1)
于是有
g n = 1 n ∑ 1 ≤ a < b ≤ n g c d ( a , b ) = 1 a + b = n 1 a + 1 b g_n=\frac{1}{n}\sum_{\begin{matrix}1\le agn=n11≤a<b≤ngcd(a,b)=1a+b=n∑a1+b1
g n = 1 n ∑ 1 ≤ a ≤ n g c d ( a , n ) = 1 1 a g_n=\frac{1}{n}\sum_{\begin{matrix}1\le a\le n\\gcd(a,n)=1\end{matrix}}\frac{1}{a} gn=n11≤a≤ngcd(a,n)=1∑a1
惊奇的发现和 f n f_n fn 的表达式扯上关系
于是
f n = f n − 1 + g n − g n − 1 f_n=f_{n-1}+g_n-g_{n-1} fn=fn−1+gn−gn−1
这真的很离谱,
然后 f n − 1 = f n − 2 + g n − 1 − g n − 2 f_{n-1}=f_{n-2}+g_{n-1}-g_{n-2} fn−1=fn−2+gn−1−gn−2
代入,一直到
f n = f 2 − g 2 + g n = 1 2 + g n f_n=f_2-g_2+g_n=\frac{1}{2}+g_n fn=f2−g2+gn=21+gn
然后只用求 g n g_n gn
接着莫比乌斯反演
g n = 1 n ∑ i = 1 n 1 i [ g c d ( i , n ) = 1 ] = 1 n ∑ i = 1 n 1 i ∑ d ∣ ( i , n ) μ d = 1 n ∑ d ∣ n μ d 1 d ∑ i = 1 ⌊ n d ⌋ 1 i = 1 n ∑ d ∣ n μ ( d ) 1 d S ( ⌊ n d ⌋ ) g_n=\frac{1}{n}\sum_{i=1}^n\frac{1}{i}[gcd(i,n)=1]=\frac{1}{n}\sum_{i=1}^n\frac{1}{i}\sum_{d|(i,n)}\mu_d\\=\frac{1}{n}\sum_{d|n}\mu_d\frac{1}{d}\sum_{i=1}^{\lfloor\frac{n}{d}\rfloor}\frac{1}{i}=\frac{1}{n}\sum_{d|n}\mu(d)\frac{1}{d}S(\lfloor\frac{n}{d}\rfloor) gn=n1i=1∑ni1[gcd(i,n)=1]=n1i=1∑ni1d∣(i,n)∑μd=n1d∣n∑μdd1i=1∑⌊dn⌋i1=n1d∣n∑μ(d)d1S(⌊dn⌋)
然后就可以 O ( n ) O(n) O(n) 算出 S ( n ) S(n) S(n)
然后由于空间限制 512 M b 512Mb 512Mb ,一个 1 e 8 1e8 1e8 的数组是 350 M b 350Mb 350Mb 左右,你不能 O ( n ) O(n) O(n) 筛出 μ \mu μ ,要将 n n n 质因数分解后类似二进制枚举搞出 g n g_n gn
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define LL long long
LL read(){
LL f=1,x=0;char c=getchar();
while(c<'0'||'9'<c){if(c=='-')f=-1;c=getchar();}
while('0'<=c&&c<='9') x=(x<<3)+(x<<1)+(c^48),c=getchar();
return f*x;
}
#define INF 0x3f3f3f3f
#define Mod 998244353
#define MAXN 100000000
inline int Sub(register int x,register int y){x-=y;return x<0?x+Mod:x;}
inline int Add(register int x,register int y){x+=y;return x>=Mod?x-Mod:x;}
inline int Mul(register LL x,register int y){x*=y;return x>=Mod?x%Mod:x;}
int Pow(int x,LL y){
int ret=1;
while(y){
if(y&1) ret=Mul(ret,x);
x=Mul(x,x);
y>>=1;
}
return ret;
}
int n,inv[MAXN+5],cnt,p[30],ans;
void DFS(int x,int d,int u){
if(x>cnt){
ans=Add(ans,Mul(Mul(u,Sub(inv[d],inv[d-1])),inv[n/d]));
return ;
}
DFS(x+1,d,u);
DFS(x+1,d*p[x],Mod-u);
return ;
}
int main(){
inv[1]=1;
for(int i=2;i<=MAXN;i++)
inv[i]=(Mod-(1ll*Mod/i*inv[Mod%i]%Mod))%Mod;
for(int i=2;i<=MAXN;i++)
inv[i]=Add(inv[i],inv[i-1]);
int T=read();
while(T--){
ans=0,cnt=0,n=read();
int tmp=n;
for(int i=2;i*i<=tmp;i++)
if(tmp%i==0){
p[++cnt]=i;
while(tmp%i==0)
tmp/=i;
}
if(tmp>1)
p[++cnt]=tmp;
if(n!=2)
DFS(1,1,1);
else ans=0;
ans=Mul(ans,Sub(inv[n],inv[n-1]));
printf("%d\n",Add(ans,inv[2]-1));
}
return 0;
}