博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
upc.2219: A^X mod P(打表 && 超越快速幂(in some ways))
阅读量:4310 次
发布时间:2019-06-06

本文共 2403 字,大约阅读时间需要 8 分钟。

2219: A^X mod P

Time Limit: 5 Sec  Memory Limit: 128 MB Submit: 417  Solved: 68 [ ][ ][ ]

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

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

Sample Output

Case #1: 14Case #2: 63

HINT

 

Source

1 #include
2 typedef long long ll ; 3 int T ; 4 int n, A, K, a, b, m, P ; 5 int small [1 << 15 | 5] ; 6 int big [1 << 15 | 5] ; 7 int ans ; 8 9 void solve ()10 {11 int ret = 0 ;12 small[0] = 1 % P ;13 for (int i = 1 ; i < (1 << 15 | 5) ; i++) {14 small [i] = (ll) small[i - 1] * A % P ;15 }16 big[0] = 1 % P ;17 for (int i = 1 ; i < (1 << 15 ) ; i++) {18 big[i] = (ll) big[i - 1] * small [1 << 15] % P ;19 }20 while (n --) {21 ret += (ll) small [K & (1 << 15) - 1] * big [K >> 15] % P ;22 if (ret >= P) ret -= P ;23 K = ((ll) a * K + b) % m ;24 }25 printf ("Case #%d: %d\n" , ++ans , ret ) ;26 }27 28 int main ()29 {30 //freopen ("a.txt" , "r" , stdin );31 scanf ("%d" , &T) ;32 ans = 0 ;33 while (T--) {34 scanf ("%d%d%d%d%d%d%d" , &n , &A , &K , &a , &b , &m , &P) ;35 solve () ;36 }37 return 0 ;38 }
View Code

 

在求A^X 幂时,快速幂求的话,是O(10^6*log(n)*40) = O(10^9) 肯定会超时,

我们将X转化成 x = i*s + j。

举例来说:

100200= 100000 + 200 ; 如果我们要求A^100200 可以 转换成求 (A^100000 ) * (A^200).

所以我们只需要将   小的数 && 大的数   分别打表存在small[] , big[]中即可。

铭神给的代码里是用二进制表示的。题目里的数据是1 ~ 10^9。所以最大不会超过1 << 30 (10亿7千多万)

所以任何一个f(x) = j         +        ((1 << 15 ) * i )       来表示

big[]     :       A^1 ,     A^2 ,     A^ 3  ,     A^ 4 …… A^s  (用s表示 1 << 15)

small[]  : A^(s * 1) , A^(s * 2) ,A^( s * 3)  ,A^( s * 4) …… A^(s * s)

这样O(1)复杂度内就能找到 A^f(x)

这样每次求A^x,便可以通过这两个数组在O(1)的时间复杂度内求出来,这样时间复杂度就变成了O(10^6*40) = O(4*10^7)了

 附代码:

转载于:https://www.cnblogs.com/get-an-AC-everyday/p/4399259.html

你可能感兴趣的文章
Hive Beeline使用
查看>>
Centos6安装图形界面(hdp不需要,hdp直接从github上下载数据即可)
查看>>
CentOS7 中把yum源更换成163源
查看>>
关于yum Error: Cannot retrieve repository metadata (repomd.xml) for repository:xxxxxx.
查看>>
linux下载github中的文件
查看>>
HDP Sandbox里面git clone不了数据(HTTP request failed)【目前还没解决,所以hive的练习先暂时搁置了】
查看>>
动态分区最佳实践(一定要注意实践场景)
查看>>
HIVE—索引、分区和分桶的区别
查看>>
Hive进阶总结(听课总结)
查看>>
大数据领域两大最主流集群管理工具Ambari和Cloudera Manger
查看>>
Sqoop往Hive导入数据实战
查看>>
Mysql到HBase的迁移
查看>>
Sqoop import进阶
查看>>
Hive语句是如何转化成MapReduce任务的
查看>>
Hive创建table报错:Permission denied: user=lenovo, access=WRITE, inode="":suh:supergroup:rwxr-xr-x
查看>>
Hive执行job时return code 2排查
查看>>
hive常用函数及数据结构介绍
查看>>
Hive面试题干货(亲自跟着做了好几遍,会了的话对面试大有好处)
查看>>
力扣题解-230. 二叉搜索树中第K小的元素(递归方法,中序遍历解决)
查看>>
力扣题解-123. 买卖股票的最佳时机 III(动态规划)
查看>>