zoukankan      html  css  js  c++  java
  • upc.2219: A^X mod P(打表 && 超越快速幂(in some ways))

    2219: A^X mod P

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

    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

    2013年山东省第四届ACM大学生程序设计竞赛

     1 #include<stdio.h>
     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
    " , ++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)了

     附代码:
  • 相关阅读:
    2016/01/14开始学习git:标签管理:操作标签
    2016/01/14开始学习git:标签管理:创建标签
    2016/01/14开始学习git:分支管理:多人协作
    2016/01/14开始学习git:分支管理:Feature分支
    2016/01/13开始学习git:分支管理:Bug分支
    python-pygame的触碰方法
    python游戏pygame模块画圆及鼠标拖拽移动方法介绍
    python的EasyGui模块简单用法介绍
    python用递归函数解汉诺塔游戏
    python函数的几种参数类型
  • 原文地址:https://www.cnblogs.com/get-an-AC-everyday/p/4399259.html
Copyright © 2011-2022 走看看