大数据计算中取模运算一错分析
1618:越狱
时间限制: 1000 ms 内存限制: 524288 KB
提交数: 223 通过数: 91
【题目描述】
原题来自:HNOI 2008
监狱有连续编号为 11 到 nn 的 nn 个房间,每个房间关押一个犯人。有 mm 种宗教,每个犯人可能信仰其中一种。如果相邻房间的犯人信仰的宗教相同,就可能发生越狱。求有多少种状态可能发生越狱。
【输入】
输入两个整数 mm 和 nn。
【输出】
可能越狱的状态数,对 100003100003 取余。
【输入样例】
2 3
【输出样例】
6
1618越狱
#include<bits/stdc++.h>
using namespace std;
int p=100003;
long long qm(long long m,long long n)
{
if(n==0)return 1;
if(n==1)return m%p;
long long t=qm(m,n/2);
t=(t*t)%p;
if(n%2)t=t*m;
return t%p;
}
int main()
{
long long m,n;
cin>>m>>n;
m%=p;
cout<<(qm(m,n)-m*qm(m-1,n-1))%p;
return 0;
}
错误代码
老规矩,样例能过,提交后一对9错(答案错误)。首先排查算法逻辑错误,想了又想,把每一个环节都从数学的角度复查一遍,还是确认逻辑没问题。那就可以是取模运算了。在朋友们的帮助下,发现(qm(m,n)-m*qm(m-1,n-1))%p可能出现负数,然后取模运算也不能把它变成正数。所以最后这一算改为(qm(m,n)-m*qm(m-1,n-1)+p)%p,但还是一对9错。期间另一朋友发了一个程序,看了下逻辑上一模一样。后来详细比较和另一朋友提醒下,发现(qm(m,n)-m*qm(m-1,n-1)+p)%p中加一个p不能解决负数问题,因为前面有一个m倍,所以需要把m*qm(m-1,n-1)也取模,最后+p就可以解决负数问题了,也就是说最后一步改为(qm(m,n)-(m*qm(m-1,n-1))%p+p)%p就可以了。
特别明谢ybt.ssoier.cn教师群里所有朋友们,你们的帮助给了我无尽的前进的动力