- 题目描述:
-
给定a0,a1,以及an=p*a(n-1) + q*a(n-2)中的p,q。这里n >= 2。 求第k个数对10000的模。
- 输入:
-
输入包括5个整数:a0、a1、p、q、k。
- 输出:
-
第k个数a(k)对10000的模。
- 样例输入:
-
20 1 1 14 5
- 样例输出:
-
8359
思路:
直接一步一步的递推肯定是要超时的。对这种求第n个数的递推题,有logn的解法。
基本思想是a(n)由a(n/2)得到,逐次循环。
由an=p*a(n-1) + q*a(n-2)
可以得到an=p2*a(n-2) + q2*a(n-4)
其中 p2 = (p*p+2*q), q2 = -q*q
这种思想是典型二分法,此题重点是学到了一种解题思想。
代码:
#include <stdio.h> #include <string.h> #include <stdlib.h> int main(void) { int p, q, p2, q2, k; long long a0, a1, a2, a3; while (scanf("%lld%lld%d%d%d", &a0, &a1, &p, &q, &k) != EOF) { if (k == 0) { printf("%lld ", a0); continue; } a0 %= 10000; a1 %= 10000; p %= 10000; q %= 10000; while (k>1) { a2 = p*a1+q*a0; while (a2<0) a2 += 1000000000; a2 %= 10000; if (k%2 == 1) { a3 = p*a2+q*a1; while (a3<0) a3 += 1000000000; a3 %= 10000; a0 = a1; a1 = a3; } else a1 = a2; p2 = (p*p+2*q)%10000; q2 = -q*q; while (q2<0) q2 += 1000000000; q2 %= 10000; p = p2; q = q2; k /= 2; } printf("%lld ", a1); } return 0; } /************************************************************** Problem: 1081 User: liangrx06 Language: C Result: Accepted Time:10 ms Memory:912 kb ****************************************************************/
#include<stdio.h> #define MOD 10000 long long a0,a1,p,q,k; void matrixpow(long long *data,long long k) { long long t1,t2,t3,t4; long long d1,d2,d3,d4; d1 = p; d2 = q; d3 = 1; d4 = 0; if(k == 1 || k == 0) return; matrixpow(data,k/2); t1 = (data[0]*data[0]+data[1]*data[2])%MOD; t2 = (data[0]*data[1]+data[1]*data[3])%MOD; t3 = (data[0]*data[2]+data[2]*data[3])%MOD; t4 = (data[1]*data[2]+data[3]*data[3])%MOD; data[0] = t1; data[1] = t2; data[2] = t3; data[3] = t4; if(k&1) { t1 = (data[0]*d1+data[1]*d3)%MOD; t2 = (data[0]*d2+data[1]*d4)%MOD; t3 = (data[2]*d1+data[3]*d3)%MOD; t4 = (data[2]*d2+data[3]*d4)%MOD; data[0] = t1; data[1] = t2; data[2] = t3; data[3] = t4; } } void main() { long long data[4]; long long res; while(scanf("%lld%lld%lld%lld%lld",&a0,&a1,&p,&q,&k)!=EOF) { data[0] = p; data[1] = q; data[2] = 1; data[3] = 0; matrixpow(data,k-2); if(k == 0) res = a0%MOD; else { if(k == 1) res = a1%MOD; else { if(k>2) res = (data[0]*p*a1+a1*q*data[2]+a0*p*data[1]+a0*q*data[3])%MOD; else res = (a1*p+a0*q)%MOD; } } printf("%lld ",res); } }