• 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;
    }
  • 相关阅读:
    C语言I博客作业08
    C语言I博客作业07
    C语言I博客作业06
    C语言I博客作业05
    C语言I博客作业04
    C语言|博客作业02
    作业02
    第一周作业
    学期总结
    第一次作业
  • 原文地址:https://www.cnblogs.com/Felix-F/p/3275808.html
Copyright © 2020-2023  润新知