【题解】HDU6760 Math is Simple (差分)
好nb的题啊
求(nle 1e8),
[f(n)=sum_{1le a<b le n,aperp b,a+bge n} {1over ab}
]
(Tle 1e4)组询问(但是你他吗std不是(O(n))的复杂度吗)
那么
[f(n)=f(n-1)+sum_{iperp n}{1over in}-sum_{a<b,a+b=n-1,qperp b} {1over ab}
]
设(g(n)=sum_{a<b,a+b=n,aperp b} {1over ab})
其实
[g(n)={1over n}sum_{1le a<ble n,a+b=n,aperp b} {a+bover ab}={1over n}sum_{aperp n-a}{1over a}={1over n}sum_{aperp n}{1over a}
]
所以
[f(n)=f(n-1)+g(n)-g(n-1)
]
所以
[f(n)=cases{
1 & n=1
\
{1over 2} & n=2
\
g (n)+{1over 2} & otherwise
}
]
然后他妈的"You can pre-calculate all (h_{0dots 10^8}) values in a second, or so."
//@winlere
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#pragma GCC optimize(3)
using namespace std; typedef long long ll;
int qr(){
int ret=0,c=getchar(),f=0;
while(!isdigit(c)) f|=c==45,c=getchar();
while( isdigit(c)) ret=ret*10+c-48,c=getchar();
return f?-ret:ret;
}
const int mod=998244353;
const int inv2=(mod+1)/2;
int h[int(1e8+5)],M[int(1e4+5)],REM[int(1e4+5)];
int MOD(const int&x){return x>=mod?x-mod:x;}
int MOD(const int&x,const int&y){return 1ll*x*y%mod;}
int mu(int n){
int ret=0;
for(int t=2;t*t<=n;++t)
if(n%t==0){
int cnt=0;
while(n%t==0) n/=t,++cnt;
if(cnt>1) return 0;
++ret;
}
if(n>1) ++ret;
return ret&1?-1:1;
}
int main(){
h[1]=1;
for(int t=2;t<=1e8;++t){
int g=mod/t;
h[t]=MOD(mod-g,h[mod-g*t]);
}
for(int t=2;t<=1e8;++t) h[t]=MOD(h[t-1]+h[t]);
int T=qr();
while(T--){
int n=qr();
ll ans=0;
if(n==2){printf("%d
",inv2); continue;}
for(int t=1;t*t<=n;++t)
if(n%t==0){
int g=n/t;
ans+=MOD(h[g],mu(t)*(h[t]-h[t-1]));
if(t*t!=n) ans+=MOD(h[t],mu(g)*(h[g]-h[g-1]));
}
printf("%d
",MOD(MOD(h[n]-h[n-1]+mod,ans%mod+mod)+inv2));
}
return 0;
}