hdu4704——Sum

这里写图片描述

emmmmm狗屁费马小定理
我们首先定义 An=S1+S2+...+Sn A n = S 1 + S 2 + . . . + S n ,所以 An+1=S1+S2+...+Sn+Sn+1 A n + 1 = S 1 + S 2 + . . . + S n + S n + 1 ,而 Sn+1 S n + 1 表示n+1个数组成n的情况数,我们考虑第一个数为 1,2,...n 1 , 2 , . . . n ,比如第一个数是1的情况, Sn+1 S n + 1 就转化为 Sn S n ,同理,最后 Sn+1=S1+S2+...+Sn S n + 1 = S 1 + S 2 + . . . + S n ,代入前式得到, An+1=2An A n + 1 = 2 A n ,因此所求的即是 2n 2 n % m m

2 n % m = ( 2 n % ( m 1 ) × 2 n m 1 ( m 1 ) ) % m = ( 2 n % ( m 1 ) ) % m × ( ( 2 n m 1 ) m 1 ) % m = 2 n % ( m 1 ) ) % m

所以,最后就是将 2n%m 2 n % m 转化为 2n%(m1)%m 2 n % ( m − 1 ) % m ,肯定快了

代码:

#include <cstdio>
#include <algorithm>
using namespace std;
const int N=100050;
const int MOD=1e9+7;
char s[N];
long long qPow(long long a,long long k){
    long long sum=1;
    while(k){
        if(k%2){
            sum=(sum*a)%MOD;
        }
        a=a*a%MOD;
        k>>=1;
    }
    return sum;
}
int main(void){
    while(~scanf("%s",s)){
        long long sum=0;
        int i=0;
        while(s[i]){
            sum=(sum*10+s[i]-'0')%(MOD-1);
            i++;
        }
        long long n=sum-1;
        printf("%lld\n",qPow(2,n));
    }
    return 0;
}
全部评论

相关推荐

07-03 11:02
中山大学 C++
字节刚oc,但距离九月秋招很近了有两段互联网实习,非腾讯字节。不敢赌转正,现在在纠结去还是不去如果实习俩月离职会有什么后果吗
阿城我会做到的:不去后悔一辈子,能否转正取决于ld的态度,只要他不卡,答辩就是走流程,个人觉得可以冲一把
投递字节跳动等公司8个岗位
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务