• poj3233 矩阵等比数列求和 二分


    对于数列S(n) = a + a^2 + a^3 +....+ a^n;

    可以用二分的思想进行下列的优化。

    if(n & 1)

      S(n) = a + a^2 + a^3 + ....... + a^n;

      = a + a^2 + a^3 +..+ a^((n-1) / 2) + a^((n-1) / 2 + 1) + a^((n-1) / 2 + 2) + ... + a^((n-1) / 2 + (n-1) / 2) + a^((n-1) / 2 + (n-1) / 2 + 1);

      = (1 + a^((n-1) / 2 + 1)) * S((n-1)/2) + a^((n-1) / 2 + 1)

    else 

      S(n) = a + a^2 + a^3 + ....... + a^n;

      = a + a^2 + a^3 +..+ a^((n / 2) + a^(n / 2 + 1) + a^(n / 2 + 2) + ... + a^(n/ 2 + n / 2);

      = (1 + a^(n / 2)) * S(n / 2);

    这样就可以避免矩阵的除法了! 还有就是MOD真的很慢。

    #include<map>
    #include<set>
    #include<string>
    #include<queue>
    #include<stack>
    #include<cmath>
    #include<vector>
    #include<cstdio>
    #include<time.h>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define INF 1000000001
    #define ll long long
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    using namespace std;
    const int MAXN = 100010;
    struct Mat
    {
        ll a[45][45];
    }E;
    int n,k,MOD;
    Mat Matadd(Mat a,Mat b)
    {
        Mat c;
        for(int i = 0; i < n; i++){
            for(int j = 0; j < n; j++){
                c.a[i][j] = (a.a[i][j] + b.a[i][j])%MOD;
            }
        }
        return c;
    }
    Mat Matmul(Mat a,Mat b)
    {
        Mat c;
        for(int i = 0; i < n; i++){
            for(int j = 0; j < n; j++){
                c.a[i][j] = 0;
                for(int k = 0; k < n; k++){
                    c.a[i][j] += (a.a[i][k] * b.a[k][j])%MOD; 
                }
                c.a[i][j] %= MOD;
            }
        }
        return c;
    }
    Mat power(Mat a,int n)
    {
        Mat c;
        c = E;
        while(n){
            if(n & 1){
                c = Matmul(c,a);
            }
            a = Matmul(a,a);
            n >>= 1;
        }
        return c;
    }
    Mat sum(Mat a,int k)//求S(k)
    {
        if(k == 1)return a;
        Mat t = sum(a,k/2);//S(k/2)
        if(k & 1){
            Mat cur = power(a,k/2 + 1);//a^(k/2 + 1)
            t = Matadd(t,Matmul(t,cur));//(1 + a^(k/2+1))*S(k/2)
            t = Matadd(t,cur);//(1 + a^(k/2 + 1))*S(k/2)
        }
        else {
            Mat cur = power(a,k/2);//a^(k/2)
            t = Matadd(t,Matmul(t,cur));//(1 + a^(k/2))*S(k/2)
        }
        return t;
    }
    int main()
    {
        while(scanf("%d%d%d",&n,&k,&MOD) != EOF){
            Mat a;
            memset(E.a,0,sizeof(E.a));
            for(int i = 0; i < n; i++)E.a[i][i] = 1;
            for(int i = 0; i < n; i++){
                for(int j = 0; j < n; j++){
                    scanf("%lld",&a.a[i][j]);
                    a.a[i][j] %= MOD;
                }
            }
            Mat ans = sum(a,k);
            for(int i = 0; i < n; i++){
                for(int j = 0; j < n; j++){
                    if(j == 0)printf("%lld",ans.a[i][j]);
                    else {
                        printf(" %lld",ans.a[i][j]);
                    }
                }
                printf("
    ");
            }
        }
        return 0;
    }
  • 相关阅读:
    判断jquery.表单验证插件是否通过验证的解决办法
    查看网站收录情况
    js面向对象基础拾遗
    查看显卡信息的DOS命令
    关于OR Mapping
    推荐两篇文章
    读书
    测试开发驱动实践
    粗略看Hibernate的代码
    开发源码的数据库群集中间件 CJDBC
  • 原文地址:https://www.cnblogs.com/sweat123/p/5439432.html
Copyright © 2020-2023  润新知