zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    PAT (Advanced Level) 1114. Family Property (25)
    PAT (Advanced Level) 1113. Integer Set Partition (25)
    PAT (Advanced Level) 1112. Stucked Keyboard (20)
    PAT (Advanced Level) 1111. Online Map (30)
    PAT (Advanced Level) 1110. Complete Binary Tree (25)
    PAT (Advanced Level) 1109. Group Photo (25)
    PAT (Advanced Level) 1108. Finding Average (20)
    PAT (Advanced Level) 1107. Social Clusters (30)
    PAT (Advanced Level) 1106. Lowest Price in Supply Chain (25)
    PAT (Advanced Level) 1105. Spiral Matrix (25)
  • 原文地址:https://www.cnblogs.com/sweat123/p/5439432.html
Copyright © 2011-2022 走看看