本文主要是介绍sdut2605 A^X mod P 山东省第四届ACM省赛(打表,快速幂模思想,哈希),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
本文出自:http://blog.csdn.net/svitter
题意:
f(x) = K, x = 1
f(x) = (a*f(x-1) + b)%m , x > 1
求出( A^(f(1)) + A^(f(2)) + A^(f(3)) + ...... + A^(f(n)) ) modular P.
1 <= n <= 10^6
0 <= A, K, a, b <= 10^9
1 <= m, P <= 10^9
本题目的关键在于大幂的分解和。。你要这样想,因为不停的求A的幂,所以肯定把算过的保存下来最合适。
打表。(- -)每次都是打表,shit。
把f分解为 fix * k + j 的形式,f就是f(x)的简称。(哈希)
然后关键是fix怎么整,多少合适。我觉得33333合适。为啥?
因为10^9 / 33333 =30000数组不大。然后余数也在33333之内,其好,那就它吧。
然后就用普通的幂模相乘打表就可以f[i] = (f[i-1] * a)mod p,这是个简单的例子,a和p没有实际含义。
这个题目我在做的时候蛋疼到二分法动态打表,但是超空间,因为不停的递归调用造成了超空间。。但是我觉得如果能够实现。。用栈的方法,应该会更加节省时间。因为用到的才计算。如果有不同的意见,请回复我,谢谢。
AC代码:
//============================================================================
// Name : math.cpp
// Author : Vit
// Version :
// Copyright : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================#include <iostream>
#include <stdio.h>
#include <string.h>
#include <cmath>using namespace std;
#define lln long long int
#define fix 33333//num
lln n, A, K, a, b, m, P;//A^f f = fix * k + j
// f = dp1 * k + dp2lln dpk[30001];
lln dpj[33334];void init()
{int i, j;//init hashdpj[1] = A;dpj[0] = dpk[0] = 1;for(i = 2; i <= 33333; i++)dpj[i] = (dpj[i-1] * A) % P;dpk[1] = dpj[33333];for(j = 1; j <= 30000; j ++)dpk[j] = (dpk[j-1] * dpk[1]) % P;
}void ace()
{//work pit;int i, t, c;lln ans, f;scanf("%d", &t);for(c = 1; c <= t; c++){scanf("%lld%lld%lld%lld%lld%lld%lld",&n, &A, &K, &a, &b, &m, &P);//initinit();f = K;ans = 0;for(i = 0; i < n; i++){ans = (ans + dpk[f/fix] * dpj[f % fix]) % P;f = (a * f + b) % m;}printf("Case #%d: %lld\n", c, ans);}
}int main()
{ace();return 0;
}
这篇关于sdut2605 A^X mod P 山东省第四届ACM省赛(打表,快速幂模思想,哈希)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!