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
  • 相关阅读:
    强制转换改变了对象的框架大小
    android应用程序fps meter[帧数显示]的分析 —— 浅谈root的风险 (1)
    父类virtual和overload,子类reintroduce; overload;
    MySQL版本与工具
    Verilog HDL实用教程笔记
    XE2安装JVCL
    解决Raize日历控件显示的问题
    hdu3415 Max Sum of Max-K-sub-sequence
    MFC重绘原理的关键理解
    常用代码页与BOM
  • 原文地址:https://www.cnblogs.com/xiaozhuyang/p/HDU4704-Sum.html
Copyright © 2011-2022 走看看