思路:其實這道題目最終的一個思想跟我之前做過的一道二進制拆分思想是一樣的。
那道題目那時候是因爲求解是次數很大上億,而我最多可以的到的是百萬級別的,因爲數組只能開到百萬
那時候我很強烈的思想就是那我就每次求解一百萬嘛。這邊的時間接近o(1)
然後重複最多也就1000次,這樣時間還是很短。
所以那時候就果斷那樣做了。
這次這道題目和那道題目有相似之處。
由於其中都是求解A的冪之和,每次冪的指數不一樣,最多達到1億。
這邊巧妙的用除和餘數的思想。快速的解決了問題。
具體思路是這樣子的。
開兩個數組,第一個數組有33333的空間,下標爲多少,表示的就是A的多少次方
另外一個數組有30000的空間,下標爲多少,表示的就是A的多少個33333的次方。
用兩個數組就可以演繹A在1-1億以內所有指數冪的快速求解,速度爲o(1)。實在YM!!學習了~~~
具體實現代碼如下。
希望以後自己遇到類似的題目能夠融會貫通。其實用這種思想去解上次的題目,好像最後的速度求解可以縮短到o(1),只不過預處理會比較長。
但是由於不需要重複求解,所以那道題目原先的做法還是比較快的,這種做法試用於多次重複問題的求解!!
那道題目鏈接:http://blog.csdn.net/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);
}
}