Sum of the Line
Consider a triangle of integers, denoted by T. The value at (r, c) is denoted by Tr,c , where 1 ≤ r and 1 ≤ c ≤ r. If the greatest common divisor of r and c is exactly 1, Tr,c = c, or 0 otherwise.
Now, we have another triangle of integers, denoted by S. The value at (r, c) is denoted by S r,c , where 1 ≤ r and 1 ≤ c ≤ r. S r,c is defined as the summation
Here comes your turn. For given positive integer k, you need to calculate the summation of elements in k-th row of the triangle S.
Now, we have another triangle of integers, denoted by S. The value at (r, c) is denoted by S r,c , where 1 ≤ r and 1 ≤ c ≤ r. S r,c is defined as the summation
Here comes your turn. For given positive integer k, you need to calculate the summation of elements in k-th row of the triangle S.
输入
The first line of input contains an integer t (1 ≤ t ≤ 10000) which is the number of test cases.
Each test case includes a single line with an integer k described as above satisfying 2 ≤ k ≤ 10^8 .
Each test case includes a single line with an integer k described as above satisfying 2 ≤ k ≤ 10^8 .
输出
For each case, calculate the summation of elements in the k-th row of S, and output the remainder when it divided
by 998244353.
by 998244353.
题意是求sigma(c=1->c=r) 。
考虑化简,可得到最终是求i从1变化到k的i与k互质的平方和。
我们可以先求不互质的。
用容斥的思想,奇加偶减,位运算枚举。
#include <bits/stdc++.h> #define maxn 100005 using namespace std; typedef long long ll; ll mod = 998244353; bool vis[maxn]; int prime[maxn]; int cnt=0; void primejudge(int n) { int i,j; vis[1]=true; for(i=2;i<=n;i++) { if(!vis[i]) { vis[i]=true; prime[cnt++]=i; } for(int j=0;j<cnt&&i*prime[j]<=n;j++) { vis[i*prime[j]]=true; if(i%prime[j]==0) break; } } } int a[15]={0}; void get_div(ll n,int &x)//唯一分解 { for(int i=0;i<cnt;i++) { if(n%prime[i]==0) { a[x++]=prime[i]; } while(n%prime[i]==0) { n/=prime[i]; } } if(n>1) a[x++]=n; } ll quick_mod(ll k,ll n) { ll res=1; while(n) { if(n&1) res=res*k%mod; k=k*k%mod; n>>=1; } return res; } ll inv(ll n) { return quick_mod(n,mod-2); } int main() { int t,i; scanf("%d",&t); primejudge(50000); while(t--) { ll n; scanf("%lld",&n); memset(a,0,sizeof(a)); int index=0; get_div(n,index); ll ans=0; ll sum=(1<<index)-1; for(i=0;i<index;i++) { ll k=n/a[i]; ans=(ans+k%mod*(k+1)%mod*(2*k+1)%mod*inv(6)%mod*a[i]%mod*a[i]%mod)%mod; } for(i=0;i<=sum;i++)//位运算枚举 { int temp=0; ll x=1; for(int j=0;j<index;j++) { if((1<<j)&i) { temp++; x=x*a[j]%mod; } } if(x!=1&&temp!=1) { ll tmpx=n/x; if(temp%2) { ans=(ans+x*x%mod*tmpx*(tmpx+1)%mod*(2*tmpx+1)%mod*inv(6)%mod)%mod; } else { ans=(ans-x*x%mod*tmpx*(tmpx+1)%mod*(2*tmpx+1)%mod*inv(6)+mod)%mod; } } } ll res=n%mod*(n+1)%mod*(2*n+1)%mod*inv(6)%mod; printf("%lld\n",(res-ans+mod)%mod); } return 0; }