洛谷 P1593 因子和 (升级版!)

题目描述

已知一个等差数列{an}的首项为 ,且对于任意两个正整数 i,j 都存在ai+aj 也在该数列中,

求所有可能的公差 d 的和,答案对 99824353 取模。

输入输出格式

输入格式:

 

输入的第一行为两个正整数 x,y。

 

输出格式:

 

输出包括一行一个整数,代表所有可能的公差 d 的和。

 

输入输出样例

输入样例#1:

2 3

输出样例#1:

15

说明

对于 10%的数据,x,y<=10,

对于 30%的数据,x,y<=100000,

对于 70%的数据,x,y<=1e9 ,

对于 100%的数据,x,y<=1e15

 

比较有意思的一道数学题。通过一点点转换就可以变成洛谷的那道题了。

首先,对于任意的ai,aj,ai+aj也在这个等差数列中。我们设aj=ai+mdai+aj=2ai+md\because ai+aj也在数列中,\thereforeai+aj=ai+md+nd\therefore 2ai+md=ai+md+nd,化简得n=\frac{ai}{d}\becauseai,n都为整数,\therefore d为整数,所有数列所有公差d的和为ai的所有因子和。所以现在只要求出x^{y}的所有因子和就行了。

 

先不管那个y次方,从x入手。对于任意一个数x,将它质因数分解。随便举个例子,对于12,质因数分解后变成了2^{2}\cdot 3^{1},它的因子则为2^{0}or3^{0}2^{1} , 3^{1} , 2^{1}\cdot3^{1} , 2^{2}\cdot3^{1},然后这些因子的和可以化为\left ( 2^{0}+2^{1}+2^{2} \right )\cdot\left ( 3^{0}+3^{1} \right ) ,不信邪的同学可以把括号拆开来或者多列举几个数来试。因此,对于任意一个数x,设其第i个质因子为pi,其最高次为ki,所有因子的和则为\prod_{i=1}^{n}\sum_{j=0}^{ki}pi^{j}

看起来这个东西很怪很难算,其实说简单点就是找到这个数每个质因子的最高次方,然后从1一直加到这个质因子的最高次方,然后把所求的和全乘起来就能得到答案了。

最后那个之前被丢弃的y次方可以捡回来了。如果一个数x的其中一个质因子p的最高次方为k,那么在x^{y}中质因子p的最高次方显然是k\cdot y,所以只需要在最高次方上面乘个y就行了。等比数列求和的话是数学必修的内容我就懒得说了直接套公式吧。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#define LL long long
using namespace std;
const int p=998244353;
long long x,y,ans=1,tot=1;
inline LL qpow(LL a, LL n)//快速幂
{
    LL ans = 1;
    while(n)
    {
        if(n & 1) ans = ans * a % p;
        a = a * a % p;
        n >>= 1;
    }
    return ans;
}
inline LL niyuan(LL b)//求逆元
{
    return qpow(b%p,p-2);
}
inline LL solve(LL a,LL b)
{
    return ((qpow(a%p,b*y+1)-1))*(niyuan(a-1))%p;//等比数列求和
} 
int main()
{
    cin>>x>>y;
    int k=sqrt(x);
    if(k<2)
        k=x;
    for(int i=2;i<=k;i++)
    {
        register LL cnt=0;
        while(!(x%i))//找到因子(其实判断是不是质因子都无所谓了毕竟第一个枚举到的肯定就是质因子)
        {
            ++cnt;
            x/=i;
        }
        if(cnt)//cnt记录最高次方
            ans=(ans*solve((LL)i,cnt))%p;
    }
    if(x>1) ans=(ans*solve(x,1))%p;//补上最后一部分。
    cout<<ans%p;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值