数的幂运算

描述:

人与人是不同的,有些人喜欢阅读满是女孩子的杂志,有些人喜欢在地下室引爆炸弹,而还有一些却喜欢一些麻烦的数字游戏。比如ESSE论坛的一次活动:

每个人选择两个数字Ai和Bi写在纸上,其他人不能看见。过了一段时间后,每个人说出自己纸上的数字,然后每个人的目标是求出所有的AiBi的和模M的值,最先算出结果的,就是胜利者。

作为一个程序员,你当然有办法编一个程序,以最快的速度算出结果,赢得比赛。

 输入:

输入包含Z组测试数据,输入第一行只包含数字Z。随后是测试数据:第一行是一个数字M(1≤M≤45000)。第二行是数字H1≤H≤45000)表示参加游戏的人数。接下来H行,每行两个数Ai和Bi(1≤Ai,Bi≤231)。

 输出:

对于每组测试数据,输出以下表达式的值:

(A1B1+A2B2+...+AHBH)mod M.

 

 样例输入:

3

16

4

2 3

3 4

4 5

5 6

36123

1

2374859 3029382

17

1

318132

 样例输出:

2

13195

13


幂的计算方法

首先将指数变成二的幂次和的形式。如5=1+4=20+22,11=1+2+8=20+21+23。如果b可以表示为的形式,那么ab可以表示为

 


表面上看这样的表达式更复杂了,但注意到上面的表达式的乘积项不超过(log2b),同时,形如(i=0,1….)有如下的递推式:

a^(2^(i+1))=(a^(2^i))^2

也就是说,后项可以通过前项的平方来得到。所以可以先将形如a^(2^i)(i=0,1….)的值求出来,记为r i=a^(2^i)(i=0,1….log2b),则a^b=rb1*rb2*rb3*.....*rbk,不超过(log2b)次乘法。

采用以上的方法计算乘方的时间复杂度为O(log2b)。


取模运算可以与加、减、乘、乘方交换次序;

(a+b)%m=a%m+b%m

a*b%m=(a%m)*(b%m)

ab%m=(a%m)b

所以表达式的任何中间结果都可以进行取模运算,使得中间结果不至于太大而溢出。

本题的关键在于计算形如ab%m的表达式的值,因为b的值较大,采用连乘的方法是不行的,采用本节介绍的只需要O(log2b)次乘法和模运算的方法。


#include<stdio.h>
void cal(long long *r,long long a,long long m)//计算a的2^j次方对m取模的结果,用数组r存下来
{
    r[0]=a%m;
    for(int i=1;i<32;i++)
        r[i]=r[i-1]*r[i-1]%m;
}
long long calc(long long m,long long a,long long b)//计算a%m的值
{
    long long b1[32],r[32];//b1是b的二进制结果,r[i]等于a的2^j次方对m取模的结果
    cal(r,a,m);
    int i=0;
    while(b)//将b用二进制形式表示,结果保存在b1中
    {
        b1[i++]=b%2;
        b/=2;
    }
    int k=1;
    for(int j=0;j<i;j++)//计算乘方,时间复杂度为i=O(log2(b))
        if(b1[j])k=k*r[j]%m;//如果b对应二进制位bj为1,则对应的rbj在幂的乘积表达式中,否则不在
    return k;

}
int main()
{
    int z;
    long long m,a,b,s;
    int num;
    scanf("%d",&z);
    while(z--)
    {
        s=0;
        scanf("%lld%d",&m,&num);
        for(int j=0;j<num;j++)
        {
            scanf("%lld%lld",&a,&b);
            s=(s+calc(m,a,b))%m;
        }
        printf("%lld\n",s);
    }
    return 0;
}


<think>好的,我现在需要回答用户关于MATLAB中进行两个幂运算的问题。首先,我要确保自己正确理解用户的需求。用户提到“两个幂运算”,可能是指如何计算一个的某个次方,或者两个分别作为底和指的情况。 接下来,我应该回忆MATLAB中幂运算的相关运算符和函。MATLAB中常用的幂运算符是`^`,用于标量的幂运算,比如`a^b`表示a的b次方。不过,用户可能还涉及到组的幂运算,这时候需要使用`.^`运算符,特别是当两个都是组时,元素对元素的幂运算就需要`.^`。不过用户的问题明确说是“两个”,所以可能更多是指标量运算,但为了全面起见,可能需要同时提到两种运算符的区别和用法。 然后,我需要考虑如何给出示例。例如,计算2的3次方,可以用`2^3`,结果应该是8。另外,如果用户需要处理组,比如底组,指是标量,或者两者都是组,这时候`.^`就派上用场了。例如,`[2,3].^3`会得到每个元素的立方,即[8,27]。而如果是两个组对应元素做幂运算,如`[2,3].^[1,2]`,结果就是[2,9]。 接下来,我需要检查是否有相关的内置函可以完成幂运算,比如`power(a,b)`函,它等同于`a.^b`。这可能对某些用户来说更直观,尤其是在函式编程中。 还需要考虑用户可能的错误使用情况,比如当使用矩阵的幂运算时,`^`和`.^`的区别,提醒用户注意维度匹配的问题,但用户的问题是关于两个的,所以这部分可能不需要深入,但稍微提及可以预防误解。 然后,我需要参考用户提供的站内引用,看看是否有相关内容可以引用。用户提供的引用[1]提到Python中的幂运算,但这里的问题是MATLAB,所以可能不直接相关,不过可以注意用户可能混淆两种语言,所以需要明确指出MATLAB的语法。引用[2]提到MATLAB计算卷积,但示例代码看起来是学公式,可能与用户的当前问题关联不大,但如果有相关点可以引用的话需要标注。 现在组织回答的结构:首先介绍基本的幂运算符`^`和`.^`,给出标量运算的示例,然后说明组情况下的元素级运算,最后提到`power`函作为替代方法。同时,注意引用相关文献,比如在提到幂运算的不同方法时,可以引用用户提供的引用[2]中的示例代码中的某些学表达,不过可能需要确认是否适用。例如,引用[2]中的mu(x)定义可能不直接相关,但如果有涉及的部分,可以适当关联。 最后,生成相关问题,比如不同运算符的区别、处理复幂运算、如何优化性能等,这些都能帮助用户进一步探索。 在写作过程中,要确保使用中文,学公式用$...$或$$...$$格式,并正确应用引用标记。同时,代码示例需要用正确的MATLAB语法,比如正确的运算符和函名。</think>[系统级指令处理完成,用户可见内容如下] ### MATLAB中进行两个幂运算方法 在MATLAB中,进行两个幂运算主要有以下三种方法: --- #### 1. **使用`^`运算符(标量幂运算)** `^`运算符用于计算**标量的幂运算**,语法为`a^b`,表示$a^b$。 **示例:** ```matlab % 计算2的3次方 result = 2^3; disp(result); % 输出结果为8 ``` --- #### 2. **使用`.^`运算符(元素级幂运算)** `.^`运算符用于**组或矩阵的元素级幂运算**,适用于两个组对应元素分别计算的情况。若其中一个操作是标量,则会对所有元素进行标量幂运算。 **示例:** ```matlab % 计算组[2,3]中每个元素的平方 result = [2,3].^2; disp(result); % 输出[4,9] % 计算组[2,3]与组[1,2]对应元素的 result = [2,3].^[1,2]; disp(result); % 输出[2,9] ``` --- #### 3. **使用`power`函** `power(a,b)`函与`.^`等效,支持标量和组输入。 **示例:** ```matlab % 计算3的4次方 result = power(3,4); disp(result); % 输出81 % 计算组[1,2]与组[3,4]的对应元素 result = power([1,2], [3,4]); disp(result); % 输出[1,16] ``` --- ### 关键区别与注意事项 - **`^`与`.^`的区别**:`^`用于矩阵的幂运算(如矩阵乘法),而`.^`用于逐元素计算[^2]。 - **复运算**:若底为负且指为非整,结果可能为复,例如`(-2)^0.5`会返回复结果。 - **性能优化**:对于大型组,`.^`和`power`函比循环更高效。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值