HDU-2256

来源:互联网 发布:mac 体验 编辑:程序博客网 时间:2024/06/05 06:51

    转载于:http://www.cnblogs.com/staginner/archive/2012/04/24/2468380.html

 
Input
The first line of input gives the number of cases, T. T test cases follow, each on a separate line. Each test case contains one positive integer n. (1 <= n <= 10^9) 
Output
For each input case, you should output the answer in one line. 
Sample Input
3125
Sample Output
997841

    题意:问你(根号2+根号3)的2n次方mod1024的结果。

    这个题目用快速幂+fmod是AC不了的,应该是浮点数精度的原因,推导的过程都体现在图上了,剩下的工作就是二分矩阵求解了。

    此外,在计算完x[n]和y[n]之后不能直接用(x[n]+(int)(y[n]*sqrt(6.0)))%1024来得到最后的结果的,先取整再模和先模再取整的结果是不一样的这一点举个例子就比较容易看出来了。

    比如(2000*1.372)%1000,这样先乘再取模得到的结果就是744,如果先把2000模1000,显然最后结果就是0了。

    

 

复制代码
#include<stdio.h>#include<string.h>#include<math.h>#define MAXD 2int N, cnt;struct Matrix{    int a[MAXD][MAXD];    void init()    {        a[0][0] = a[1][1] = 5, a[0][1] = 12, a[1][0] = 2;    }}mat[150];int multiply(int x, int y){    int i, j, k, z = ++ cnt, ans;    for(i = 0; i < 2; i ++)        for(j = 0; j < 2; j ++)        {            ans = 0;            for(k = 0; k < 2; k ++)                ans += mat[x].a[i][k] * mat[y].a[k][j];            mat[z].a[i][j] = ans & 1023;        }    return z;}int powmod(int n){    int k;    if(n == 1)        return 0;    k = powmod(n >> 1);    k = multiply(k, k);    if(n & 1)        k = multiply(k, 0);    return k;}void solve(){    int k, ans, x, y;    cnt = 0;    mat[0].init();    k = powmod(N);    ans = (2 * mat[k].a[0][0] - 1 + 1024) & 1023;    printf("%d\n", ans);}int main(){    int t;    scanf("%d", &t);    while(t --)    {        scanf("%d", &N);        solve();    }    return 0;}
复制代码