二进制算法--指数取余( (m^n)%k=? )

本文介绍了一种快速计算(m^n)%k的算法,并提供了两种不同的C++代码实现方式。一种是简洁高效的实现,另一种则增加了输出中间过程的代码,便于理解和调试。这两种实现都利用了位操作和循环来减少乘法次数,从而提高了计算效率。
ACE-Step

ACE-Step

音乐合成
ACE-Step

ACE-Step是由中国团队阶跃星辰(StepFun)与ACE Studio联手打造的开源音乐生成模型。 它拥有3.5B参数量,支持快速高质量生成、强可控性和易于拓展的特点。 最厉害的是,它可以生成多种语言的歌曲,包括但不限于中文、英文、日文等19种语言

描述:m,n,k,为整数,求 (m^n)%k=?


正经代码:

#include<stdio.h>
using namespace std;
int main(){
    int m,n,k;
    scanf("%d%d%d",&m,&n,&k);
    int ans=1;
    for(;n;n>>=1,m=(long long)m*m%k)
        if(n&1)
            ans=(long long)ans*m%k;
    printf("%d\n",ans);
    return 0;
}

代码牛皮*:

#include<stdio.h>
#include<iostream>
using namespace std;
int main(){
    int m,n,k;
    scanf("%d%d%d",&m,&n,&k);
    int ans=1;
cout<<"m="<<m<<"  n="<<n<<"  k="<<k<<endl;
    for(;n;n>>=1,m=(long long)m*m%k){
cout<<"  --------\n  n="<<n<<endl<<"  n>>1 ="<<(n>>=1)<<endl;
cout<<"  m="<<m<<endl;
        if(n&1)
            ans=(long long)ans*m%k;
cout<<"  n&1="<<(n&1)<<endl<<"  ans="<<ans<<endl;
    }
    printf("%d\n",ans);
    return 0;
}

运行结果1,2,3,:


 


 

 

 

 

您可能感兴趣的与本文相关的镜像

ACE-Step

ACE-Step

音乐合成
ACE-Step

ACE-Step是由中国团队阶跃星辰(StepFun)与ACE Studio联手打造的开源音乐生成模型。 它拥有3.5B参数量,支持快速高质量生成、强可控性和易于拓展的特点。 最厉害的是,它可以生成多种语言的歌曲,包括但不限于中文、英文、日文等19种语言

#include<stdio.h> #include<stdlib.h> /* 函数申明 */ int long_n(int n); int shuru(char *arr, int k, char *wei, int is_first); void jiami(char *arr, int k, int e, int n); /* 输入函数,记录从键盘输入的明文*/ int shuru(char *arr, int k, char *wei, int is_first) { int i; char ch; /*判断是否为第一分组的输入,如果是则获输入的字符,否则就将上一分组最后获的字符作为这一分组的第一个字符*/ if (is_first == 1) ch = getchar(); else ch = *wei; for (i = 0; (i < k) && (ch != '\n');i++) //获字符直到获到回车符为止 { arr[i] = ch; ch = getchar(); } *wei = ch; //最后获到的字符准备作为下一分组的第一个字符 for (i = i; i < k; i++) arr[i] = 'a'; //输入不够一组个数的整数倍则补'a'(即为补零) if (ch == '\n') //接收到回车符返回0,否则为1 return 0; else return 1; } /*加密函数*/ void jiami(char *arr, int k, int e, int n) { int m = 0,c=1, i, j,t=0, shu,temp,num=0; int *array; /*Mi赋值过程*/ for (i = 0; i < k; i++) { temp = 1; for (j = 0; j < (k-i-1)*2; j++) temp = temp * 10; shu = (int)arr[i] - 97; m = m + temp * shu; } temp = e; /*获e的二进制表达形式的位数*/ do{ temp = temp / 2; num++; } while (temp != 0); array = (int *)malloc(sizeof(int)*k); //申请动态数组 temp = e; /*动态数组存储e的二进制表达形式*/ for (i = 0; i < num; i++) { array[i] = temp % 2; temp = temp / 2; } /*避免出现天文数字的算法,详情见上文文字说明*/ for (i = num - 1; i >= 0; i--) { t = t * 2; temp = c*c; if (temp > n) { for (j = 0; temp - n*j >= 0; j++); j--; c = temp - n*j; } else c = temp; if (array[i] == 1) { t = t + 1; temp = c*m; if (temp > n) { for (j = 0; temp - n*j >= 0; j++); j--; c = temp - n*j; } else c = temp; } e = e / 2; } temp = c; i = 0; /*c的位数小于分组长度则在前补零*/ do{ temp = temp / 10; i++; } while (temp != 0); for (i; i < num; i++) printf("0"); printf("%d", c); } /*获分组的长度*/ int long_n(int n) { int temp,i,j,k,shi,comp=0; temp = n; /*获n的位数*/ for (i = 1; temp / 10 != 0; i++) { temp = temp / 10; } temp = i; /*若n的位数为基数*/ if (i % 2 != 0) { i = i - 1; return i; } /*若位数为偶数*/ else { for (j = 0; j < i/2; j++) { shi = 1; for (k = 0; k < temp - 2; k++) shi = shi * 10; comp = comp + shi * 25; temp = temp - 2; } if (comp <= n) return i; else { i = i - 2; return i; } } } /*主函数*/ int main() { int p, q, e, d, n, fai_n, k, i,is_first=1; char ch,*arr,wei='a'; printf("请输入p、q、e值,用空格间隔开\n"); scanf("%d%d%d", &p, &q, &e); //从键盘获p、q、e值 n = p*q; fai_n = (p-1)*(q-1); //Φ(n) for (k = 0; (k*n + 1) % e != 0; k++); if ((k*n + 1) % e == 0) d = (k*n + 1) / e; //d * e ≡ 1 (mod Φ(n)) k = long_n(n); k = k / 2; //分组的长度 ch = getchar(); //缓冲回车符 arr = (char *)malloc(sizeof(char)*k); //申请动态数组 printf("请输入明文\n"); while (1) { i=shuru(arr,k,&wei,is_first); //调用输入字符的函数,接收到回车符返回0,否则为1 is_first = 0; //第一分组录入结束设为0 jiami(arr,k,e,n); //调用加密函数 if (i == 0) //接收到返回值为0跳出循环 break; } printf("\n"); return 0; } 检查一下这个代码的错误
05-17
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值