思路:其实这道题目最终的一个思想跟我之前做过的一道二进制拆分思想是一样的。
那道题目那时候是因为求解是次数很大上亿,而我最多可以的到的是百万级别的,因为数组只能开到百万
那时候我很强烈的思想就是那我就每次求解一百万嘛。这边的时间接近o(1)
然后重复最多也就1000次,这样时间还是很短。
所以那时候就果断那样做了。
这次这道题目和那道题目有相似之处。
由于其中都是求解A的幂之和,每次幂的指数不一样,最多达到1亿。
这边巧妙的用除和余数的思想。快速的解决了问题。
具体思路是这样子的。
开两个数组,第一个数组有33333的空间,下标为多少,表示的就是A的多少次方
另外一个数组有30000的空间,下标为多少,表示的就是A的多少个33333的次方。
用两个数组就可以演绎A在1-1亿以内所有指数幂的快速求解,速度为o(1)。实在YM!!学习了~~~
具体实现代码如下。
希望以后自己遇到类似的题目能够融会贯通。其实用这种思想去解上次的题目,好像最后的速度求解可以缩短到o(1),只不过预处理会比较长。
但是由于不需要重复求解,所以那道题目原先的做法还是比较快的,这种做法试用于多次重复问题的求解!!
那道题目链接:http://blog.youkuaiyun.com/u013611908/article/details/43614307
AC代码:
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define fix 33333
int n, A, K, a, b, m, p;
long long mi[30005];
long long yu[33334];
void init()
{
mi[0] = 1;
yu[0] = 1;
yu[1] = A;
for (int i = 2; i <= 33333; i++)
yu[i] = (yu[i - 1] * A) % p;
mi[1] = yu[33333];
for (int j = 2; j <= 30000; j++)
mi[j] = (mi[j - 1] * mi[1]) % p;
}
int main()
{
int t;
cin >> t;
int icase = 1;
while (t--)
{
scanf("%d%d%d%d%d%d%d", &n, &A, &K, &a, &b, &m, &p);
long long ans=0;
init();
long long f = K;
while (n--)
{
ans = (ans + mi[f / fix] * yu[f%fix]) % p;
f = (a*f + b) % m;
}
printf("Case #%d: %lld\n", ans);
}
}