CSU - 1752 童话故事生成器
来源:互联网 发布:ubuntu 16.04 飞秋 编辑:程序博客网 时间:2024/04/27 23:14
题目:
Description
机器人宝宝又要听机器人妈妈讲故事了。由于机器人宝宝的记忆力超常,所以机器人妈妈每天讲的故事都要接在上一个故事后面。假设机器人妈妈讲的第一个故事是X1,那么第二个是X2,第i个是Xi= (a * Xi-1 + b) % c + 1。现在你希望知道第n天机器人妈妈讲的故事是什么。
Input
第一行输入一个整数 T (1 <= T <= 100) 表示有T组数据;
接下来每一行输入5个整数X1(1<=X1<=1000000) , a(1<=a<=1000000) , b(1<=b<=1000000) , c(1<=c<=1000000) , n(2<=n<=1e18);
Output
求第n天机器人妈妈讲的故事是什么;
Sample Input
21 1 1 1000 2394706 314559 674595 559832 4431920000000001
Sample Output
3554658
首先我们注意到,Xi= (a * Xi-1 + b) % c + 1这个式子的取值范围是1到c
也给我们带来了很大的方便,只需要求出与Xn mod c同余的任何一个数,即可得到Xn
所以上式可以这么写:Xi≡a * Xi-1 + b+1 (mod c)
所以,Xi≡X1*a^(n-1)+(b+1)*(a^(n-2)+......+a^2+a+1) (mod c)
所以,Xn=(X1*mi_a_c(n - 1)+(b+1)*sum(n-2)-1)%c+1
感觉一点破绽都没有,可是就是WA。
WA的代码:
#include<iostream>using namespace std;long long t, x, a, b, c;long long mi_a_c(long long n){if (n == 0)return 1;long long s = mi_a_c(n / 2);s = s*s;if (n % 2)s *= a;return s%c;}long long sum(long long n){if (n == 0)return 1;long long s = sum(n / 2);s += (s + n % 2 - 1)*mi_a_c((n + 1) / 2);return s%c;}int main(){long long n;cin >> t;while (t--){cin >> x >> a >> b >> c >> n;x *= mi_a_c(n - 1);x += (b + 1)*sum(n - 2);cout << (x - 1) % c + 1 << endl;}return 0;}
没办法,只好单独对2个函数进行测试,还真发现了问题所在。
原来,sum函数中的s += (s + n % 2 - 1)*mi_a_c((n + 1) / 2);这一句有问题
s + n % 2 - 1可能会得到-1,所以把s + n % 2 - 1改成s + n % 2 - 1+c就AC 了。
然后我又用矩阵快速幂做了一遍,也AC了。
代码:
#include<iostream>using namespace std;long long t, x, a, b, c;long long a11, a12, a21, a22;void mi(long long n){if (n == 0){a11 = a22 = 1;a12 = a21 = 0;return;}mi(n / 2);long long b11 = (a11*a11 + a12*a21) % c, b12 = (a11*a12 + a12*a22) % c;long long b21 = (a11*a21 + a21*a22) % c, b22 = (a21*a12 + a22*a22) % c;a11 = b11, a12 = b12, a21 = b21, a22 = b22;if (n % 2){a12 += a11, a22 += a21;a11 *= a, a21 *= a;a11 %= c, a12 %= c, a21 %= c, a22 %= c;}}int main(){long long n;cin >> t;while (t--){cin >> x >> a >> b >> c >> n;mi(n-1);cout << (x*a11 + (b+1)*a12 - 1) % c + 1 << endl;}return 0;}
2个代码的效率是不一样的。
后面的矩阵快速幂比较快,是log n
前面的快速幂是log n + log (n/2) +log (n/4) +......=(log n)^2 / 2
不过常数不一样,矩阵是2*2的,所以后面的是4* log n,前面的是(log n)^2 / 2
- CSU - 1752 童话故事生成器
- 童话故事
- 法国童话故事《小王子》读后感
- CSU
- CSU
- CSU
- CSU
- CSU
- CSU
- CSU
- CSU
- CSU
- CSU
- CSU
- CSU
- CSU
- CSU
- CSU
- POJ 2406(kmp)
- IDA* POJ 2331
- 浅谈:ATML在自动测试系统中的应用
- POJ2195——Going Home
- Table 'user_xxxxx' is marked as crashed and should be repaired
- CSU - 1752 童话故事生成器
- Spring Security学习笔记
- C++ 优先队列的使用
- 各路Android开发大牛的博客
- 如何将英文版ubuntu11.10中文版
- 只用getchar函数读入一个整数
- Android中Gson解析json数据使用@SerializedName注解与java对象不匹配的字段
- UVa 10047
- Makefile浅尝