Hint: ACM-ICPC 2017 Asia Urumqi: K. Sum of the Line
做法:通过打表或手写,我们很容易发现,第k行的S就是gcd(x,k) = x 的平方和
当k为奇数时,我们可以直接利用 1^2 +2^2 +3^2 +4^2 +...+n^2 = n(n+1)(2n+1)/6 来求
当k为偶数时。比如k = 4时
那一行的T 为 1 0 3 0 S = 1^2+3^2
我们会发现,k的质因子及其倍数是无贡献的,即0
所以这时候我们可以用到容斥原理,如果是k的质因子d
我们就可以剔除d^2 * (1^2+2^2+……+(k/d)^2)
AC代码:
#include<bits/stdc++.h>
#define rep(i,s,t) for(int i = (int)(s); i <= (int)(t); i++)
#define rev(i,t,s) for(int i = (int)(t); i >= (int)(s); i--)
#define pb(x) push_back(x)
#define all(x) x.begin(),x.end()
#define sz(x) (int)(x).size()
using namespace std;
typedef long long ll;
const int mod = 998244353;
const double PI = 4*atan(1.0);
const int maxn = 1e5+5;
const int INF = 0x3f3f3f3f;
int fac[maxn];
ll inv[15];
int cnt;
inline int read()
{
char x;
while((x = getchar())<'0' || x>'9');
int u = x-'0';
while((x = getchar())>='0' && x<='9') u = (u<<3)+(u<<1)+x-'0';
return u;
}
void dec(int N)//质因数分解
{
int t = N;
for(int j=2;j*j<=t;j++){
if(t%j == 0){
fac[cnt++] = j;
while(t%j == 0) t/=j;
}
}
if(t>1) fac[cnt++] = t;
}
ll calc(int n)//1^2 +2^2 +3^2 +4^2 +...+n^2 = n(n+1)(2n+1)/6
{
return 1ll*n*(n+1)%mod*(2*n+1)%mod*inv[6]%mod;
}
ll cal(int n) //枚举子集的容斥原理
{
int flag;
ll tmp;
ll sum = 0;
for(int i=1;i<(1<<cnt);i++)
{
tmp = 1; flag = 0;
for(int j=0;j<cnt;j++)
{
if(i&(1<<j)){
flag++;
tmp = tmp*fac[j];
}
}
if(flag&1) sum = (sum+(tmp*tmp)%mod*calc(n/tmp))%mod;
else sum = (sum-(tmp*tmp)%mod*calc(n/tmp)%mod+mod)%mod;
}
// cout<<calc(n)<<endl;
// cout<<sum<<endl;
// cout<<cnt<<endl;
return (calc(n)-sum+mod)%mod;
}
void inv_table()
{
inv[1] = 1;
for(int i=2;i<=10;i++)
inv[i] = 1ll*(mod-mod/i)*inv[mod%i]%mod;
}
int main()
{
#ifdef LOCAL_FILE
freopen("in.txt","r",stdin);
#endif // LOCAL_FILE
int t;
inv_table();
t = read();
while(t--)
{
memset(fac,0,sizeof(fac));
cnt = 0;
int k = read();
dec(k);
printf("%lld\n",cal(k));
}
return 0;
}