[POJ]P1845 Sumdiv

原题链接:P1845 Sumdiv

题意

给定$A,B$,求$A^B$对9901取模的值。

分析

先说说我的第一思路:模数是很小的,完全可以开一个桶放下所有的幂次方。

所以我们可以把每个数分解质因数了,然后把每个质数的所有幂次方装进桶里。

然后我们从$1$到$9901$枚举每一位,同时统计他们的个数积,最后答案加上(个数积$\times$幂次方积)就可以了。。

 

发现时间有点爆炸。。。

而且这些所谓的优化好像是用处不大的。。

 

考虑从数论的层面上解决??

首先$$A^B=p_1^{Ba_1}\times p_2^{Ba_2}\times \cdots \times p_m^{Ba_m}$$

那么所有的质因数的和就是枚举每一位指数

我们先提取含$p_1$的式子

$$\sum_{k_1,k_2,\cdots ,k_m}^{k_1\leq Ba_1,k_2\leq Ba_2,\cdots ,k_m\leq Ba_m}{({p_1}^{k_1}+{p_2}^{k_2}+\cdots +{p_m}^{k_m})(\cdots)}$$

然后我们把后面的也化简之后,每个因数就剩下它的等比数列求和了,我们利用求和公式

最后答案就是$$\sum_{i=1}^m{\frac{p_i^{Ba_i+1}-1}{p_i-1}}$$

我们对每一个$p_i-1$求一下逆元就ok了。

 

但是这道题真的这么简单吗。。。

逆元通常求法是费马小定理或是exgcd,这些都要求模数与求的数互质。。

这道题显然不一定互质。。

怎么办呢?

$x=\frac{a}{b} \mod{p}=\frac{a\mod pb}{b}$

这样就可以了(写了一上午心态爆炸)。。

 

代码

 1 #include <iostream>
 2 #include <cstring>
 3 #include <set>
 4 #include <algorithm>
 5 #include <cstdio>
 6 #include <cmath>
 7 #define ll long long
 8 #define ull unsigned long long
 9 #define Mid ((l+r)<<1)
10 using namespace std;
11 const int N=2e7+1009;
12 const ll mod=9901;
13 ll read(){
14     char c;ll num,f=1;
15     while(c=getchar(),!isdigit(c))if(c=='-')f=-1;num=c-'0';
16     while(c=getchar(), isdigit(c))num=num*10+c-'0';
17     return f*num;
18 }
19 ll a,b,ans=1;
20 ll ksc(ll x,ll y,ll md){
21     return (x*y-(ll)((long double)x/md*y)*md+md)%md;     
22 }
23 ll Pow(ll a,ll p,ll md){
24     ll ans=1;
25     for(;p;p>>=1,a=ksc(a,a,md))
26         if(p&1)ans=ksc(a,ans,md);
27     return ans;
28 }
29 int main()
30 {
31     //cout<<ksc(111,111)<<endl;
32     a=read();b=read();
33     if(a==0){
34         printf("0\n");
35         return 0;
36     }
37     for(int i=2;i<=sqrt(a);i++){
38         if(a%i)continue;
39         int num=0;
40         while(a%i==0)num++,a/=i;
41         ans=ksc(ans,(Pow(i,num*b+1,mod*(i-1))+(mod*(i-1))-1)/(i-1),mod);
42     }
43     if(a>1)
44         ans=ksc(ans,(Pow(a,b+1,mod*(a-1))+(mod*(a-1))-1)/(a-1),mod);
45     printf("%lld\n",ans);
46     return 0;
47 }
View Code

 

转载于:https://www.cnblogs.com/onglublog/p/10322544.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值