HDU 4704 [费马小定理+快速幂] ---狗眼不识多校

Description

Input

2

Output

2

        
 
   
   
Hint
1. For N = 2, S(1) = S(2) = 1. 2. The input file consists of multiple test cases.

Sample Input

2

Sample Output

2

        
  

Hint

   
   
1. For N = 2, S(1) = S(2) = 1. 2. The input file consists of multiple test cases.


PS:据说是2013的多校第9场的题,简直烧脑子,至今写这篇题解仍旧没有绕过来一个点,过阵子再回来看看吧;

题目大意:给你一个N , 求S(1)+ S(2) +...+S(n) 的组合数 , 其中S(K)代表可以把N拆分为K个数字 的情况数。 特别绕脑子;

举例分析:

1.当N=1 ,  S(1)  = 1 , 因为N=1可以拆成1这一个数字   , 所以答案是  1 

2.当N=2 . S(1) = 1 ,因为N=2,拆成1个数字,还是2 ,一种情况;  S(2) 是代表可以拆分为2个数字, 那边是 1 和 1  一种情况, 所以答案是  2

3.当N=3,S(1) = 1 ;  S(2) = (1+2) || (2+1) ; S(3) = 3 ;   所以答案是  1 + 2 + 1 = 4 ;

4.当N=4, S(1) = 1 ; S(2) = (2+2)||(1+3)||(3+1) ; s(3) = (1+1+2)||(1+2+1)||(2+1+1) ; S(4) = 4 ; 所以答案是 1+3+3+1 = 8 ;

推规律发现 , find的答案就是  2^(n-1) ; 但是题中的N特别大, 所以就得考虑如何去化简这个n;

这里首先知道 a^b%mod 可以用快速幂解决, 那么 a^n%mod , 且题中mod是一个质数, 所以可以用费马小定理去解决;

费马小定理:a^(p-1)%p = 1 (这里的p就是mod,且p是一个质数)

化简:   a^n%p =  a^(n%(p-1))%p     所以答案就是求 n % (p-1) , 随后字符串读入然后不断对新生成的n % p-1 即可 ;

对如上进行推导: 首先对于一个整数n可以做如此拆分: n = k(p-1)+n%(p-1) 其中k为系数,p为去摸数

那么对于本题 a^n%p = a^(k(p-1)+n%(p-1))%p ----> a^(k*(p-1))%p * a^(n%(p-1))%p , 前者就是费马小定理,答案为1,系数k不影响

所以推出 化简所事;

本题告一段落QAQ

AC代码:

#include <iostream>
#include <cstdio>
#define ll long long 
#define mod 1000000007
using namespace std;
ll quick(ll a , ll b)
{
    ll res = 1 ;
    a = a % mod ;
    while(b)
    {
        if(b&1)  res = res * a %mod ;
        b>>=1;
        a = a * a %mod ;
    }
    return res ; 
}
int main()
{
    char s[500000] ;
    while(scanf("%s",s)!=EOF)
    {
        ll n = 0 ; 
        for(int i = 0 ; s[i] ; i++)
            n = n*10 + (s[i]-'0') , n%=mod-1;
        if(!n) printf("1\n");
        else cout<<quick(2,n-1)<<endl; 
    }
    return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Kelisita

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值