zoukankan      html  css  js  c++  java
  • HDU4704Sum 费马小定理+大数取模

    题目链接

      http://acm.hdu.edu.cn/showproblem.php?pid=4704

    题目大意

      看似复杂,其实就是求整数n的划分数,4=1+1+2和4=1+2+1是不同的。因而可知答案是2n-1

    题目分析:

      因为n实在是太大太大了,这可咋办啊?!n<10100000

      做这场的时候没有注意到,也是当时没有看过什么是费马小定理,居然跟模值有关系!mod=1000000007。这个mod有什么特点呢?它是个质数。

      费马小定理揭示了:当p是一个素数并且a和p互质时,ap-1 %p≡1。

      那么在这道题里a=2,p=mod。显然满足费马小定理。再根据同余模定理

      当n>p时:设m=n-p。那么an-1=am+p-1=ap-1*am。因而an-1%p=am+p-1%p=((ap-1%p )*(am%p))%p=1*am%p。

      这么我们就可以断定mod-1是一个循环节。先用大数对它取模,然后数据量就可以承受得起了,再用快速幂,这道题就解了!

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 using namespace std;
     5 const int MAX=100005;
     6 const int mod=1000000007;
     7 char s[MAX];
     8 
     9 long long pow(long long a,long long b)
    10 {
    11     long long base=a,r=1;
    12     while(b!=0)
    13     {
    14         if(b&1) r=(r*base)%mod;
    15         base=(base*base)%mod;
    16         b>>=1;
    17     }
    18     return r%mod;
    19 }
    20 
    21 int main()
    22 {
    23     while(scanf("%s",s)!=EOF)
    24     {
    25         int len=strlen(s);
    26         long long num=0;
    27         for(int i=0;i<len;i++)//大数取模
    28             num=(num*10+(int)(s[i]-'0'))%(mod-1);
    29         if(num==0)//说明num=mod-1
    30         {
    31             cout<<pow(2,mod-2)<<endl;
    32         }
    33         else
    34         {
    35             num--;
    36             cout<<pow(2,num)<<endl;
    37         }
    38     }
    39     return 0;
    40 }
    HDU4704
  • 相关阅读:
    ECharts之柱状图 饼状图 折线图
    Vue自定义指令(directive)
    HDU 1231 最大连续子序列
    POJ 2533 Longest Ordered Subsequence
    HDU 1163 Eddy's digital Roots
    HDU 2317 Nasty Hacks
    HDU 2571 命运
    HDU 4224 Enumeration?
    HDU 1257 最少拦截系统
    HDU 2740 Root of the Problem
  • 原文地址:https://www.cnblogs.com/xiaozhuyang/p/HDU4704-Sum.html
Copyright © 2011-2022 走看看