HDU 4704 Sum 超大数幂取模

很容易得出答案就是2^(n-1)

但是N暴大,所以不可以直接用幂取模,因为除法操作至少O(len)了,总时间会达到O(len*log(N)) 显然爆的一塌糊涂

套用FZU1759的模板+顺手写一个大数-1

http://acm.fzu.edu.cn/problem.php?pid=1759


标程的做法是用费马小定理 , ap-1≡1(mod p) 

那么2(1e9+6)%(1e9+7) = 1 

很容易得出 2k%(10e+7) = 2k%(10e+6)%(10e+7) 

然后就能用快速幂了 但FZU那题显然不是这么水的...我暂时也没看懂是怎么做的


 现在看懂这个意思了,根据著名的欧拉公式:A^PHI(C)=1(MOD C) 条件:(A,C)=1 

 我们可以得出以下公式 

 那么这题就能做了..显然是以Phi(c)作为循环节 ... 但我还是没理解当(A,C)!=1时这个公式的成立性 ....prpr 

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#define LL long long
#define nnum 100005
#define nmax 131625
int flag[nmax], prime[nmax];
char ch[nnum];
int plen;
void mkprime() {
    int i, j;
    memset(flag, -1, sizeof(flag));
    for (i = 2, plen = 0; i < nmax; i++) {
        if (flag[i]) {
            prime[plen++] = i;
        }
        for (j = 0; (j < plen) && (i * prime[j] < nmax); j++) {
            flag[i * prime[j]] = 0;
            if (i % prime[j] == 0) {
                break;
            }
        }
    }
}
int getPhi(int n) {
    int i, te, phi;
    te = (int) sqrt(n * 1.0);
    for (i = 0, phi = n; (i < plen) && (prime[i] <= te); i++) {
        if (n % prime[i] == 0) {
            phi = phi / prime[i] * (prime[i] - 1);
            while (n % prime[i] == 0) {
                n /= prime[i];
            }
        }
    }
    if (n > 1) {
        phi = phi / n * (n - 1);
    }
    return phi;
}
int cmpCphi(int p, char *ch) {
    int i, len;
    LL res;
    len = strlen(ch);
    for (i = 0, res = 0; i < len; i++) {
        res = (res * 10 + (ch[i] - '0'));
        if (res > p) {
            return 1;
        }
    }
    return 0;
}
int getCP(int p, char *ch) {
    int i, len;
    LL res;
    len = strlen(ch);
    for (i = 0, res = 0; i < len; i++) {
        res = (res * 10 + (ch[i] - '0')) % p;
    }
    return (int) res;
}
int modular_exp(int a, int b, int c) {
    LL res, temp;
    res = 1 % c, temp = a % c;
    while (b) {
        if (b & 1) {
            res = res * temp % c;
        }
        temp = temp * temp % c;
        b >>= 1;
    }
    return (int) res;
}
void solve(int a, int c, char *ch) {
    int phi, res, b;
    phi = getPhi(c);
    if (cmpCphi(phi, ch)) {
        b = getCP(phi, ch) + phi;
    } else {
        b = atoi(ch);
    }
    res = modular_exp(a, b, c);
    printf("%d
", res);
}
char* sub(char ch[]){
    int len = strlen(ch);
    int fl = 1;
    char x[nnum];
    for(int i = len-1 ; i >= 0 ; i--){
        x[i] = ((ch[i] - fl - '0') + 10) % 10 + '0';
        if((ch[i] - fl - '0') < 0 ) fl = 1;
        else fl = 0;
    }
    x[len] = '';
    if(x[0] == '0') return x+1;
    return x;
}
int main() {
    int a = 2, c = 1000000007;
    mkprime();
    while (~scanf("%s",ch)) {
        char x[nmax];
        strcpy(x,sub(ch));
        //puts(x);
        solve(a % c, c, x);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/Felix-F/p/3275808.html