题目链接:https://nanti.jisuanke.com/t/28970
题目大意:1~k中与k不互质的数字取0,求这个序列的后缀和,然后对后缀和加和求结果
题目思路:很明显最后一个数字会被k个数字都当作后缀和的加数,倒数第二个会被k-1个,所以如果单单是1~k的后缀和,应该是,易知该和等于
,所以我们现在需要去掉与k不互质的数字造成的影响。用刚才那个理论很容易得出,去掉一个数字对该和的影响只需减去该数字的平方。所以我们只需要获得k的质因数,他的质因数的倍数都是要被去掉的。但是这里还有一个需要注意的地方,那就是可能会减重了,比如6既是2的倍数又是3的倍数,所以这里我们需要用到容斥,如果一共有num个数字,那么就是一共有
-1种情况(不能一个都不要,所以0需要被排除),只需要用1~
的十进制所对应的二进制就能表示所有情况,奇加偶减。
由这个公式发现,将
提取出来以后,就变成了
然后减掉这些就行了。
以下是代码:
#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define MAXN 100005
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
#define MOD 998244353
int factor[15],num;
ll quickpow(ll x,ll y){
if(!y)return 1;
ll temp=quickpow(x,y/2);
temp*=temp;
temp%=MOD;
if(y&1){
temp*=x;
temp%=MOD;
}
return temp;
}
ll six=quickpow(6,MOD-2);
void solve(int n){
rep(i,2,sqrt(n)){
if(n%i==0){
factor[num++]=i;
while(n%i==0)n/=i;
}
}
if(n>1)factor[num++]=n;
}
ll sum(ll n){
ll ans=(((((n*(n+1))%MOD)*(2*n+1))%MOD)*six)%MOD;
return ans;
}
int main(){
int t,k;
scanf("%d",&t);
while(t--){
num=0;
scanf("%d",&k);
solve(k);
ll ans=sum(k),temp=0;
rep(i,1,(1<<num)-1){
int cnt=0,t=1;
ll anss=1;
rep(j,0,num-1){
if(i&t){
anss=(factor[j]*anss)%MOD;
cnt++;
}
t<<=1;
}
if(cnt&1){
temp=(temp+(((anss*anss)%MOD)*sum(k/anss)))%MOD;
}
else{
temp=(temp-(((anss*anss)%MOD)*sum(k/anss)))%MOD;
}
}
ans=(ans-temp+MOD)%MOD;
printf("%lld\n",ans);
}
return 0;
}