山东第四届省赛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 }

 

 

你可能感兴趣的:(c)