• 【hdu4704】 Sum——费马小定理+快速幂取模


    题目链接

    题目的大意就是要求把一个数划分为m(1<=m<=n)个数相加之和的方案数(答案取模1e9+7)。

    容易想到答案就是sum(C(n-1,i)(0<=i<=n-1)),也就是2^(n-1)(组合数第n行的所有数的和为2^(n-1))。

    既然答案是2n-1,第一反应应该是快速幂取模。很可惜,这里的n巨大无比,这种做法显然是不现实的。于是我们就需要用到费马小定理啦。

    我们知道 ap-1%p=1,那么我们令n=t*(p-1)+k,即n-1=t*(p-1)+(k-1)。那么2n-1=2t*(p-1) * 2k-1,重点来了!根据同余的性质,2t*(p-1) %p=1。也就是说我们只需要求出2k-1%p的值,这个值就是最后的答案,变形到这里,求出k的值就可以用快速幂了。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 const int mod=1e9+7;
     5 typedef long long LL;
     6 using namespace std;
     7 char ch[1000005];
     8 int len;
     9 LL kuai(int aa,LL b)
    10 {
    11     LL res=1;LL a=aa;
    12     while(b){
    13         if(b&1)res=res*a%mod;
    14         a=a*a%mod;
    15         b>>=1;
    16     }
    17     return res;
    18 }
    19 LL fei(int p)
    20 {
    21     LL ans=0;
    22     for(int i=1;i<=len;i++)
    23         ans=(ans*10+ch[i]-48)%p;
    24     return ans;
    25 }
    26 int main()
    27 {
    28     while(~scanf("%s",ch+1)){
    29         len=strlen(ch+1);
    30         LL k=fei(mod-1);
    31         LL an=kuai(2,k-1);
    32         printf("%lld
    ",an);
    33     }
    34     return 0;
    35 }
    hdu4704
  • 相关阅读:
    hdoj5813【构造】
    Codeforces645B【树状数组求逆序数】
    pojcoin【未完待续】
    hdoj5818【模拟】
    poj2385【基础DP】
    poj3069【贪心,水】
    谦虚
    poj3617【贪心】
    poj2229【完全背包-规律Orz...】
    poj3176【简单DP】
  • 原文地址:https://www.cnblogs.com/JKAI/p/7445267.html
Copyright © 2020-2023  润新知