ACM-较大的数乘法取模技巧*

(有任何问题欢迎留言或私聊 && 欢迎交流讨论哦

 比如模数是1e15这种,相乘的时候爆LL了,但是又不想用大数,咋办呢?

文章目录


###快速乘
类似快速幂,很好敲,但是多了一个log! here

long long ksc(long long a, long long b, long long mod){
    long long res = 0;
    while(b){
        if(b&1) res = (res + a)%mod;
        (a<<=1)%=mod;
        b >>= 1;
    }
    return res;
}

###模拟
找一个较小的数模拟一波 here

LL qsc(LL x,LL y){
    LL a1=x/1000000,a2=x%1000000,b1=y/1000000,b2=y%1000000;
    LL t=a1*b1%p*1000000%p*1000000%p;
    t=(t+a2*b2%p);
    t=(t+a1*b2%p*1000000%p);
    t=(t+a2*b1%p*1000000%p);
    return t%p;
}

###转long double再搞回来
《算法竞赛进阶指南》
听说很稳?
a ∗ b &ThickSpace; m o d &ThickSpace; p = a ∗ b − ⌊ a ∗ b p ⌋ ∗ p a∗b\;mod \;p = a∗b−⌊\frac{a∗b}{p}⌋*p abmodp=abpabp
用long double来计算 ⌊ a ∗ b p ⌋ ⌊\frac{a∗b}{p}⌋ pab,误差很小,因为long double的特性是存不下就舍弃低位,再把它转成long long。直接用long long来计算。long long爆掉了会让符号位出错,但是小于2^63的位是不会挂的,这正好符合我们的需求。

LL mul(LL a,LL b,LL mo){
    LL tmp=(a*b-(LL)((long double)a/mo*b+1e-8)*mo);
    return tmp<0?tmp+mo:(tmp>=mo?tmp-mo:tmp);
}
LL mul(LL x, LL y,LL mo) {
    LL z = (long double) x * y / mo; z = x * y - z * mo;
    if(z < 0) z += mo; else if(z > mo) z -= mo;
    return z;
}

https://blog.csdn.net/WerKeyTom_FTD/article/details/50437196
https://blog.csdn.net/alan_cty/article/category/613965

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值