山东第四届省赛C题: A^X mod P

http://acm.sdibt.edu.cn/JudgeOnline/problem.php?id=3232

 

Problem C:A^X mod P

Time Limit: 5 Sec  Memory Limit: 128 MB
Submit: 10  Solved: 2
[Submit][Status][Discuss]

Description

 

 

It's easy for ACMer to calculate A^X mod P. Now given seven integers n, A, K, a, b, m, P, and a function f(x) which defined as following.

f(x) = K, x = 1

f(x) = (a*f(x-1) + b)%m , x > 1

 

Now, Your task is to calculate

( A^(f(1)) + A^(f(2)) + A^(f(3)) + ...... + A^(f(n)) ) modular P.

 

 

Input

 

 

In the first line there is an integer T (1 < T <= 40), which indicates the number of test cases, and then T test cases follow. A test case contains seven integers n, A, K, a, b, m, P in one line.

1 <= n <= 10^6

0 <= A, K, a, b <= 10^9

1 <= m, P <= 10^9

 

 

Output

 

 

For each case, the output format is “Case #c: ans”. 

c is the case number start from 1.

ans is the answer of this problem.

 

 

Sample Input

2
3 2 1 1 1 100 100
3 15 123 2 3 1000 107

Sample Output

Case #1: 14
Case #2: 63

HINT

 

Source

山东省第四届ACM程序设计大赛2013.6.9

 

和昨天做的福大的很像,但不是。

题目意思很简单,比赛用了枚举的方法,知道会超时,40组测试数据。

 

时间复杂度 o(n)=10^6*40*logn ==>10^9  每计算一个a^p%m logn

怎么做?

( A^(f(1)) + A^(f(2)) + A^(f(3)) + ...... + A^(f(n)) ) modular P.

看来别人的思路,才想到拆分。有了这个思想,就容易起来了,就是哈希。保存结果,每一次遇到,直接读取。避免了重复计算。

A^n=A^(k*x+y);

n=k*x+y;==>(A^k)^x * A^y;

A^k和A^y可以用一个dp1[ ]数组保存起来。这样就解决一个了。

(A^k)^x也用一个数组 dp2[ ]保存起来。

式子就可以转化为 A^n= dp2[n/k]*dp1[n%k]; 对比一下 (A^k)^x * A^y;

K取多大呢???10^6? 太大了,超了,没有必要这么大。

因为:

f(x) = (a*f(x-1) + b)%m , x > 1

f(x)最大是10^9   所以K=33333就足够了。

 

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<cstring>
 5 #define HH 33000
 6 #define GG 33000
 7 using namespace std;
 8 
 9 
10 long long   dp1[1000003];
11 long long   dp2[1000003];
12 
13 void make_ini(long long  A,long long P)
14 {
15     long long  i;
16     dp1[0]=dp2[0]=1;
17     dp1[1]=A;
18     for(i=2;i<=HH;i++)
19     dp1[i]=(dp1[i-1]*A)%P;//A^k
20 
21     dp2[1]=dp1[HH];
22     for(i=2;i<=GG;i++)
23     dp2[i]=(dp1[HH]*dp2[i-1])%P;
24 }
25 
26 long long  make_then(long long  K,long long  n,long long  A,long long  a,long long  b,long long  m,long long  P)
27 {
28     long long  ans=0,i,j,tmp;
29     tmp=K;
30     for(i=1;i<=n;i++)
31     {
32         ans=(ans+dp2[tmp/HH]*dp1[tmp%HH])%P;
33         tmp=(a*tmp+b)%m;
34     }
35     return ans;
36 }
37 
38 
39 int main()
40 {
41     long long  T,n,A,K,a,b,m,P,i,tmp;
42     while(scanf("%lld",&T)>0)
43     {
44         for(i=1;i<=T;i++)
45         {
46             scanf("%lld%lld%lld%lld%lld%lld%lld",&n,&A,&K,&a,&b,&m,&P);
47             make_ini(A,P);
48             tmp=make_then(K,n,A,a,b,m,P);
49             printf("Case #%lld: %lld\n",i,tmp);
50         }
51     }
52     return 0;
53 }

 

 

posted @ 2013-08-14 11:35  芷水  阅读(336)  评论(0编辑  收藏  举报