Sumdiv Page17 分治/逆元

Sumdiv Page17 分治/逆元

书上的分治方法就不提了

加深一下这题的数论解法

先将A做唯一分解

对于 p 1 b k 1 − 1 p 1 − 1 % 9901 {{p_1^{bk_1}-1}\over p_1-1}\%9901 p11p1bk11%9901,可以求出 p 1 − 1 p_1-1 p11在模 9901 9901 9901意义下的逆元(由于 p 1 p_1 p1肯定是个质数,所以可以用费马小定理求解逆元)

但是有逆元的前提是 p 1 − 1 p_1-1 p11 9901 9901 9901互质,由于 9901 9901 9901本身是个质数,所以他们两个数不互质的数学表达式为 ( p 1 − 1 ) % 9901 = 0 ({p_1-1})\%9901=0 (p11)%9901=0。这种情况下的处理为将等比公式还原回去,即计算 ( 1 + p 1 + p 1 2 + . . . p 1 b k 1 ) % m o d (1+p_1+{p_1}^2+...{p_1}^{bk_1})\%mod (1+p1+p12+...p1bk1)%mod,由于 p 1 % 9901 = 1 , p 1 2 % 9901 = p 1 % 9901 × p 1 % 9901 = 1 × 1 = 1 , . . . p 1 b k 1 % 9901 = 1 p_1\%9901=1,{p_1}^2\%9901=p_1\%9901×p_1\%9901=1×1=1,...{p_1}^{bk_1}\%9901=1 p1%9901=1,p12%9901=p1%9901×p1%9901=1×1=1,...p1bk1%9901=1,故其结果为 b k 1 + 1 bk_1+1 bk1+1 1 1 1相加

代码

#define ll long long
#define rep(x,a,b) for (int x=a;x<=b;x++)
#define WW(x) printf("%lld\n",x)
const ll mod=9901;
int mm,a,b;
struct node
{
    ll x,num;
}p[maxn];
ll qpow(ll a,ll b,ll mod)
{
    ll res=1;
    while(b)
    {
        if (b&1)res=(res*a)%mod;
        a=(a*a)%mod;
        b>>=1;
    }
    return res;
}
void solve(int x)
{
    rep(i,2,int(sqrt(x)))
    {
        if (x%i==0)
        {
            ll num=0;
            while(x%i==0)
            {
                x/=i;num++;
            }
            p[mm].x=i;
            p[mm++].num=num;
        }
    }
    if (x>1)
    {
        p[mm].x=x;
        p[mm++].num=1;
    }
}
int main()
{
    while(~scanf("%d%d",&a,&b))
    {
        mm=0;
        solve(a);
        ll ans=1;
        repp(i,0,mm)
        {
            ll x=p[i].x;
            ll num=p[i].num;
            if ((x-1)%mod==0)
            {
                ans=ans*(1+b*num)%mod;
            }
            else
            {
                ll inv=qpow(x-1,mod-2,mod);
                ll pow=qpow(x,b*num+1,mod)-1;
                ans=ans*pow%mod*inv%mod;
            }
        }
        while(ans<0)ans+=mod;
        WW(ans);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值