hdu 3416 最短路+最大流
博弈论——取石子问题(转)

hdu 2256

scturtle posted @ 2010年9月06日 05:12 in algorithm , 1920 阅读

一道比较难想的数学题+矩阵乘法题,这个题Jesful同学迅速AC真是犀利啊,首先题目是求floor((sqrt(2)+sqrt(3))^(2*n))就是求floor((5+2*sqrt(6))^n),考虑(5+2*sqrt(6))^n最后等于a+b*sqrt(6)那么(5-2*sqrt(6))^n就应该等于a-b*sqrt(6),所以有(5+2*sqrt(6))^n+(5-2*sqrt(6))^n=2*a,然后可以观察到(5-2*sqrt(6))^n远小于1 所以floor((5+2*sqrt(6))^n+(5-2*sqrt(6))^n)=2*a,也就是说floor((5+2*sqrt(6))^n)=2*a-1,所以只需求得a即可,求a的话就是用递推,即是说构造矩阵用矩阵乘法解决,这样时间复杂度为O(logn)----wr大牛

#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
struct mat{int a11,a12,a21,a22;};
mat m[31];
int a,b;

void init()
{
    m[0].a11=5; m[0].a12=2;
    m[0].a21=12;m[0].a22=5;
    for(int i=1;i<=30;i++)
    {
        m[i].a11=(m[i-1].a11*m[i-1].a11+m[i-1].a12*m[i-1].a21)%1024;
        m[i].a12=(m[i-1].a11*m[i-1].a12+m[i-1].a12*m[i-1].a22)%1024;
        m[i].a21=(m[i-1].a21*m[i-1].a11+m[i-1].a22*m[i-1].a21)%1024;
        m[i].a22=(m[i-1].a21*m[i-1].a12+m[i-1].a22*m[i-1].a22)%1024;
    }
}

void modexp(int n)
{
    a=1,b=0;
    int oa,ob;
    for(int i=0;i<=30&&n;i++)
    {
        if(n&1<<i)
        {
            oa=a;ob=b;
            a=(oa*m[i].a11+ob*m[i].a21)%1024;
            b=(oa*m[i].a12+ob*m[i].a22)%1024;
            n-=1<<i;
        }
    }
}

int main()
{
#ifndef ONLINE_JUDGE
    freopen("in","r",stdin);
    freopen("out","w",stdout);
#endif
    init();
    int cas,n;scanf("%d",&cas);
    while(cas--)
    {
        scanf("%d",&n);
        modexp(n);
        printf("%d\n",(a+a+1024-1)%1024);
    }
}

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter