UVa 10006 快速幂运算

知识补充:

  • 如果a和b关于m同于,那么(a - b )是m的整数倍。
  • 负数取余运算:不同的语言有不同的方法,其中C和JAVA是按第一个数的符号确定结果的符号,C++则要依据系统而定。 取余运算的发展:

    1.(a+b)%p=(a%p+b%p)%p

    2.(a?b)%p=(a%p?b%p)%p

    3.(a?b)%p=(a%p?b%p)%p

    4.(ab)%p=((a%p)b)%p

  • 费马定理:对于一个不能被p整除的数a:

    ap≡a mod p

    ap?1≡1 mod p

  • 快速幂算法(求xn%mod):

有两种实现方式:

1.二进制实现:

把xn定界化为二进制表示的形式,然后用取余公式实现。如

x22=x2?x4?x16(原理是:22的二进制表示为10110)

然后计算:

( ((x2%mod)?(x4%mod)%mod)?(x16%mod)%mod)%mod

2.递归实现(实际是二进制实现倒着的形式):

原理是:如果n是偶数就求(x?x)n/2,这样一直递归下去,直到n/2为0为递归出口。如果n是奇数就求(x?x)n/2x,这样一直递归下去,直到n/2为0为递归出口。

代码部分:

二进制实现快速幂:

typedef long long LL;

LL mod(LL x, LL n, LL mod) {
    LL res = 1;
    while (n > 0) {
        if (n & 1) res = res * (x % mod) % mod;
        n >>= 1;
        x = x * x;
    }
    return res;
}

递归实现代码

typedef long long LL;

LL mod(LL x, LL n, LL mod) {
    if (n == 0) return 1;
    LL res = mod(x * x % mod, n / 2, mod);
    if (n & 1) res = res * x %mod;
    return res;
}

UVa 10006的代码:

#include <iostream>
#include <cmath>
#include <algorithm>
#include <cstdio>
using namespace std;
typedef long long LL;

LL doit(LL x, LL n, LL mod) {
    LL res = 1;    //从2的0次方开始
    while (n > 0) {
        if (n & 1) res = res * x % mod;
        x = x * x % mod;
        n >>= 1;
    }
    return res;
}

bool isprime(int x) {
    for (int i = 2; i * i <= x; i++) {
        if (x % i == 0) return false;
    }
    return x != 1;
}

int main(void)
{
    int n;
    while (scanf("%d", &n), n) {
        bool ans = true;
        if (isprime(n)) { printf("%d is normal.\n", n); continue; }
        for (int i = 2; i < n; i++) {
            if (doit(i, n, n) != i) {
                ans = false;
                break;
            }
        }
        if (ans) printf("The number %d is a Carmichael number.\n", n);
        else printf("%d is normal.\n", n);
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-11 01:20:47

UVa 10006 快速幂运算的相关文章

【分治】快速幂运算-递归与非递归方法

问题 Q: [分治]快速幂运算 时间限制: 1 Sec  内存限制: 128 MB提交: 14  解决: 9[提交][状态][讨论版] 题目描述 邪狼:“老大,好像还是不够油钱啊?”修罗王:“看来只好用我的独门绝技----能力增持术了.”邪狼:“听说能量增持数很霸道的?”修罗王:“没错,假设初始燃油能提供的能量为X,当我对它进行能量增持n秒后,该然后的能量将达到Xn”邪狼:“这么强大的技能啊,简直逆天了,不过怎么之前不见老大用过?”修罗王:“偶尔偷偷用几次没关系,经常用,燃油公司会找我麻烦的.”

快速幂运算(非大数)

快速幂顾名思义,就是快速算某个数的多少次幂.其时间复杂度为 O(log?N), 与朴素的O(N)相比效率有了极大的提高. 下面以3­16 为例: 一般运算方式是: 316 = 3*3*3*3……*3 这样的话需要运算15次 而快速幂运算的方式是: 316 = (32)8 = ((32)2)4 = (((32)2)2)2 这样的话只需要运算4次 不难看出,快速幂运算其实就是每次运算时把底数平方,指数减半,从而提高效率. 显然,当指数为奇数时,我们要作一些特殊处理: 以711为例: 711 = 71

POJ 1845 Sumdiv【同余模运算+递归求等比数列和+快速幂运算】

快速幂运算在第一次训练时候就已经遇到过,这里不赘述 同余模运算也很简单,这里也不说了,无非是(a+b)%m (a*b)%m 把m弄到里面变成(a%m+b%m)%m   (a%m*b%m)%m 今天学的最重要的还是递归二分求等比数列 题目大意是给出A和B,求A^B的约数和 解这个题,首先,对A进行素因子分解得到 (PI(pi^ai))^B 然后我们有约数和公式: 对A=PI(p1^k1) A的所有因子之和为S = (1+p1+p1^2+p1^3+...p1^k1) * (1+p2+p2^2+p2^

快速幂运算

快速幂运算顾名思义,就是快速算某个数的多少次幂.其时间复杂度为 O(log?N), 与朴素的O(N)相比效率有了极大的提高. 以下以求a的b次方来介绍 把b转换成二进制数. 该二进制数第i位的权为 例如 11的二进制是1011 11 = 2³×1 + 2²×0 + 2¹×1 + 2º×1 因此,我们将a¹¹转化为算 代码如下 int pow3(int a,int b) { intr=1,base=a; while(b!=0) { if(b&1) r*=base; base*=base; b>

[ACM] hdu 3923 Invoker (Poyla计数,快速幂运算,扩展欧几里得或费马小定理)

Invoker Problem Description On of Vance's favourite hero is Invoker, Kael. As many people knows Kael can control the elements and combine them to invoke a powerful skill. Vance like Kael very much so he changes the map to make Kael more powerful. In

快速幂运算模板

ll pow(ll a,ll b) //long long型 { ll ans=1; while(b!=0) { if(b%2==1) //if(b&1) ans=ans*a%mod;//如果是奇数次幂,因为b下面是除以2操作,会少一次乘,这里要提前乘上去. a=a*a%mod;//快速幂,每一次是上一次的平方倍 b=b/2; } return ans; } 分析: 将指数b看成二进制,b%2==1即判断当前b二进制最低位是否为1,是则将当前底数a与累积ans相乘,否则跳过.在每次循环中都将底数

UVa 11582 (快速幂取模) Colossal Fibonacci Numbers!

题意: 斐波那契数列f(0) = 0, f(1) = 1, f(n+2) = f(n+1) + f(n) (n ≥ 0) 输入a.b.n,求f(ab)%n 分析: 构造一个新数列F(i) = f(i) % n,则所求为F(ab) 如果新数列中相邻两项重复出现的话,则根据递推关系这个数列是循环的. 相邻两项所有可能组合最多就n2中,所以根据抽屉原理得到这个数列一定是循环的. 求出数列的周期,然后快速幂取模即可. 1 #include <cstdio> 2 #include <iostrea

基础快速幂运算

浅析快速幂 首先,举个例子(假设数据全为long long型). 例题:输入a,n, 求a的n次方(a > 0). 看到这个例题,肯定是思路滚滚来啊,不就是相当于n个a相乘吗?于是乎,就上代码了: #include<iostream> using namespace std; long long ans(long long &a, long long &n) { long long sum = 1; for (int i = 1; i <= n; i++) { su

uva 1374 快速幂计算

#include <iostream> #include <cstdio> #include <cmath> #include <cstring> #include <algorithm> #include <cstdlib> #include <stack> #include <cctype> #include <string> #include <malloc.h> #include