[HDU1852] Beijing 2008 [唯一分解定理][除法取模]

[ L i n k \frak{Link} Link]


有多组测试数据。
每组给定 N , K \small\rm N,K N,K,令 S \small\rm S S 200 8 N \small\rm{2008^N} 2008N的正因数和 σ ( 200 8 N ) \small\rm{\sigma(2008^N)} σ(2008N) M ≡ S ( m o d K ) \small\rm{M\equiv S\pmod{K}} MS(modK)
200 8 M ( m o d K ) \small\rm{2008^M\pmod{K}} 2008M(modK)

1 ≤ N ≤ 1 0 7 \small\rm1\le N\le 10^7 1N107 500 ≤ K ≤ 1 0 4 \small\rm500\le K\le 10^4 500K104


要求的是 [ 200 8 σ ( 200 8 N ) % K ] % K {\left[2008^{\sigma(2008^N)\%K}\right]\%K} [2008σ(2008N)%K]%K。我们先设 k = ω ( 200 8 N ) \small k=\omega(2008^N) k=ω(2008N)
数据范围很大,所以暴力应该是不行的,首先得对公式做一些简化。
提起因数,我就想到唯一分解定理
(1) 200 8 N = ∏ i = 1 k p i a i {2008^N=\prod\limits_{i=1}^{k}p_i^{a_i}}\tag{1} 2008N=i=1kpiai(1)
那么, σ ( 200 8 N ) \small\sigma(2008^N) σ(2008N)呢?
(2) σ ( 200 8 N ) = ∏ i = 1 k ∑ j = 1 a i p i j \sigma(2008^N)=\prod\limits_{i=1}^k\sum\limits_{j=1}^{a_i}p_i^j\tag{2} σ(2008N)=i=1kj=1aipij(2)
我们知道等比数列求和公式
(3) ∑ i = 1 n a 1 q i − 1 = a 1 ⋅ 1 − q n 1 − q \sum\limits_{i=1}^na_1q^{i-1}=a_1\cdot\frac{1-q^n}{1-q}\tag{3} i=1na1qi1=a11q1qn(3)
( 2 ) \small(2) (2) ( 3 ) \small(3) (3),得到:
(4) σ ( 200 8 N ) = ∏ i = 1 k p i ⋅ 1 − p i a i 1 − p i \sigma(2008^N)=\prod\limits_{i=1}^kp_i\cdot\frac{1-p_i^{a_i}}{1-p_i}\tag{4} σ(2008N)=i=1kpi1pi1piai(4)
x \small x x对模 K \small K K的逆元为 x − 1 \small x^{-1} x1。那么:
(5) σ ( 200 8 N ) ≡ ∏ i = 1 k p i ( 1 − p i a i ) ( 1 − p i ) − 1 ( m o d K ) \sigma(2008^N)\equiv\prod\limits_{i=1}^k p_i(1-p_i^{a_i})(1-p_i)^{-1}\pmod{K}\tag{5} σ(2008N)i=1kpi(1piai)(1pi)1(modK)(5)
这是一种处理除法取模的方法。但是逆元有一个条件!要求逆元的那个应该和 K K K互质!!


那我们就要思考一下除法取模还有什么办法了。
首先,很显然 ( 1 − p i ) ∣ ( 1 − p i a i ) (1-p_i)|(1-p_i^{a_i}) (1pi)(1piai),那么,设 η = σ ( 200 8 N ) m o d    K \eta=\sigma(2008^N)\mod{K} η=σ(2008N)modK
(6) η = { ∏ i = 1 k ( p i m o d    K ) ⋅ ( 1 − p i a i ) m o d    [ ( 1 − p i ) ⋅ K ] ( 1 − p i ) m o d    K } m o d    K \eta=\left\{\prod\limits_{i=1}^k(p_i\mod{K})\cdot\frac{(1-p_i^{a_i})\mod{[(1-p_i)\cdot K]}}{(1-p_i)}\mod{K}\right\}\mod{K}\tag{6} η={i=1k(pimodK)(1pi)(1piai)mod[(1pi)K]modK}modK(6)
这个应该还是蛮容易推的?
(推 ∀ a , b ∈ N ∗ \mathbf\forall a,b\in\N^* a,bN a ∣ b a|b ab a b m o d    c = a m o d    b c b m o d    c \dfrac{a}{b}\mod{c}=\dfrac{a\mod{bc}}{b}\mod{c} bamodc=bamodbcmodc就可以了。也挺显然的。)
(当然你也可以上下分解质因数,不过我觉得挺麻烦的,万一爆常数了呢。)


现在,我们只需要利用 ( 6 ) \small(6) (6)求出 η \small \eta η

但是怎么对 200 8 N \small 2008^N 2008N分解质因数?——设 2008 = ∏ i = 1 m p i t i \small2008=\prod\limits_{i=1}^mp_i^{t_i} 2008=i=1mpiti
(7) 200 8 N = ∏ i = 1 m p i t i N 2008^N=\prod\limits_{i=1}^mp_i^{t_iN}\tag{7} 2008N=i=1mpitiN(7)
利用 ( 7 ) \small(7) (7),又因为对 2008 \small2008 2008做质因数分解不难,我们可以先唯一分解 2008 \small2008 2008
(8) 2008 = 251 ∗ 2 3 2008=251*2^3\tag{8} 2008=25123(8)
考虑到并不用真的计算出 200 8 N \small2008^N 2008N:我们只需要分别记录 p i \small p_i pi t i N \small t_iN tiN就可以了。
(9) 200 8 N = 2 3 N 50 1 N \small2008^N=2^{3N}501^N\tag{9} 2008N=23N501N(9)



然后求 200 8 η ( m o d K ) \small2008^{\eta}\pmod{K} 2008η(modK)
这样就可以解决这道题目了。


#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<cctype>
#include<algorithm>
using namespace std;
long long defpowm(long long a, long long b, long long m) {
    long long ans = 1;
    while(b) {
        if (b&1) {
            ans*=a;
            ans%=m;
        }
        a*=a;
        a%=m;
        b>>=1;
    }
    return ans;
}
int main() {
    long long n, k;
    while(~scanf("%lld%lld", &n, &k)) {
        if (n==0&&k==0) break;
        long long temp0 = k*250ll;
        long long temp1 = defpowm(251, n+1, temp0) - 1;
        long long temp2 = defpowm(2, 3*n+1, temp0) - 1;
        long long ans = temp1*temp2/250; ans %= k;
        printf("%lld\n", defpowm(2008, ans, k));
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值