ICPC2017 Urumqi 容斥原理

 Sum of the Line

时间限制: 1 Sec  内存限制: 128 MB
提交: 211  解决: 61
[提交] [状态] [讨论版] [命题人:admin]

题目描述

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.

样例输入

扫描二维码关注公众号,回复: 2908407 查看本文章
2
2
3

样例输出

1
5

来源/分类

ICPC2017  Urumqi 

解题思路:

观察T三角形数组,可以发现,题目是让求所有与k互质的的数的平方之和。

对于第k行,先将k质因数分解。然后二进制枚举出k之内与k不互质的数的平方和

这个可以利用公式1^2+2^2....=n*(n+1)*(2n+1)/6;

然后就是我第一次分解质因数的没有将2单独拿出来超时,

将2拿出来单独分为一种情况,其他的就只有i是奇数的情况。

#include<bits/stdc++.h>
using namespace std;
#define LL long long
const LL mod = 998244353;
LL ni;
 
LL qpow(LL a,LL k)
{
    LL tm=1;
    while(k)
    {
        if(k&1)
            tm=(tm*a)%mod;
        a=(a*a)%mod;
        k>>=1;
    }
    return tm;
}
 
LL sum(LL x,LL k)
{
    LL s=(((x*x)%mod)*(((k*(k+1)%mod)*(2*k+1)%mod)*ni%mod))%mod;
    return s;
}
 
LL solve(LL n)
{
    LL a[200];
    LL temp=n;
    int k=0;
    for(int i=2;i*i<=n;)
    {
        if(temp%i==0)
        {
            a[k++]=i;
            while(temp%i==0)temp/=i;
        }
        if(temp==1)break;
        if(i==2)i++;
        else i+=2;
    }
    if(temp!=1)a[k++]=temp;
    LL ans=0;
    for(int i=1;i<(1<<k);i++)
    {
        LL x=1;
        int s=0;
        for(int j=0;j<k;j++)
        {
            if(i&(1<<j))
            {
                x=x*a[j];
                s++;
            }
        }
       // cout<<x<<" "<<s<<endl;
        if(s&1)ans+=sum(x,n/x);
        else ans-=sum(x,n/x);
    }
    return (ans+mod)%mod;
}
 
 
int main()
{
   // freopen("in.txt","r",stdin);
   // freopen("w1.txt","w",stdout);
    int t;
    scanf("%d",&t);
    ni = qpow(6LL,mod-2);
    while(t--)
    {
        LL k;
        scanf("%lld",&k);
        LL ans=(((k*(k+1)%mod)*(2*k+1)%mod)*ni%mod)%mod;
        //LL ans=(((k*(k+1)%mod)*(2*k+1)%mod)*ni%mod)%mod;
        ans=(ans-solve(k)+mod)%mod;
        printf("%lld\n",ans);
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_40894017/article/details/81975559