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.

 

输入

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 .

 

输出

For each case, calculate the summation of elements in the k-th row of S, and output the remainder when it divided
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;
}

  

 

posted @ 2018-08-22 10:53  行远山  阅读(185)  评论(0编辑  收藏  举报