POJ 3233 Matrix Power Series(java)

题目链接:http://poj.org/problem?id=3233

类型:矩阵快速幂+二分
题解:
S1=A1;
S2=A1+A2=A1x(1+A1)=A1xS1;
S3=A1+A2+A3=A1x(1+A1)+A3=A1xS1+A3;
S4=A1+A2+A3+A4=A2x(1+A1+A2)=A2xS2;
然后这道题一开始是从高到低二分,发现tle了,然后选择了从低到高 就ac了;

从高往低使用二分的代码(tle)

package POJ3233;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;

public class Main {
    static Matrix matrix;
    static Matrix m;
    static int mod;
    static StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
    static PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));

    public static int nextInt() throws IOException {
        in.nextToken();
        return (int) in.nval;
    }

    public static String next() throws IOException {
        in.nextToken();
        return (String) in.sval;
    }
    static class Matrix {
        int a[][];
        int n;

        public Matrix(int n) {
            super();
            a = new int[n][n];
            this.n = n;
        }


        public Matrix() {
            super();
        }


        public Matrix Add(Matrix m) {
            Matrix ans = new Matrix(m.n);
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < n; j++) {
                    ans.a[i][j]=(a[i][j] + m.a[i][j])%mod;
                }
            }
            return ans;
        }

        public Matrix Multi(Matrix m) {
            Matrix ans = new Matrix(m.n);
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < n; j++) {
                    for (int k = 0; k < n; k++) {
                        ans.a[i][j] += a[i][k] * m.a[k][j];
                    }
                    ans.a[i][j]%=mod;
                }
            }
            return ans;
        }
    }
    public static void main(String[] args) throws IOException {
        int n = nextInt();
        int k = nextInt();
        mod = nextInt();
        matrix = new Matrix(n);
        m= new Matrix(n);
        for (int i = 0; i < n; i++)
            for (int j = 0; j < n; j++)
                matrix.a[i][j] = nextInt()%mod;
        m.a=matrix.a;
        Matrix ans=getsum(k);
        for (int i = 0; i < n; i++) {
            out.print(ans.a[i][0]);
            for (int j = 1; j < n; j++)
                out.print(" "+ans.a[i][j]);
            out.println();
        }
        out.flush();
    }

    static Matrix getsum( int sum) {
        if (sum == 1)
            return m;
        else if (sum % 2 == 0) {
            return quick(matrix, sum >>1)
                    .Multi(getsum(sum >>1))
                    .Add(getsum( sum >>1));
        } else {
            return quick(matrix, sum >>1)
                    .Multi(getsum( sum >>1))
                    .Add(getsum( sum >>1 ))
                    .Add(quick(matrix, sum));
        }

    }

    static Matrix quick(Matrix n, int m) {
        m--;
        Matrix t = new Matrix(n.n);
        t.a = n.a;
        while (m != 0) {
            if ((m & 1) == 1)
                t.Multi(n);
            n.Multi(n);
            m >>= 1;
        }
        return t;
    }
}

AC代码


import java.io.BufferedInputStream;
import java.util.Scanner;

public class A {
    static Scanner in = new Scanner(new BufferedInputStream(System.in));
    static long mod;

    static class Mat {
        public long a[][];
        public int x;

        public Mat(int x) {
            a = new long[x][x];
            this.x = x;
        }

        public Mat mu(Mat t) {
            Mat ans = new Mat(x);
            for (int i = 0; i < x; i++) {
                for (int j = 0; j < x; j++) {
                    for (int k = 0; k < x; k++) {
                        ans.a[i][j] += a[i][k] * t.a[k][j];
                    }
                    ans.a[i][j] %= mod;
                }
            }
            return ans;
        }

        public Mat add(Mat t) {
            Mat ans = new Mat(x);
            for (int i = 0; i < x; i++) {
                for (int j = 0; j < x; j++) {
                    ans.a[i][j] = (a[i][j] + t.a[i][j]) % mod;
                }
            }
            return ans;
        }

        public Mat() {
            super();
        }

    }

    static Mat E;

    static void setE(int s) {
        E = new Mat(s);
        for (int i = 0; i < s; i++)
            E.a[i][i] = 1;
    }

    static Mat Z;

    static void setZ(int s) {
        Z = new Mat(s);
    }

    static Mat A;

    static void setA(int s) {
        A = new Mat(s);
        for (int i = 0; i < s; i++) {
            for (int j = 0; j < s; j++) {
                A.a[i][j] = in.nextLong() % mod;
            }
        }
    }

    static class M {
        public Mat a[][];

        public M() {
            a = new Mat[2][2];
        }

        public void set(Mat t, Mat b, Mat c, Mat d) {
            a[0][0] = t;
            a[0][1] = b;
            a[1][0] = c;
            a[1][1] = d;
        }

        public M mu(M t) {
            M ans = new M();
            ans.a[0][0] = E;
            ans.a[1][0] = Z;
            ans.a[0][1] = t.a[0][1].add(a[0][1].mu(t.a[1][1]));
            ans.a[1][1] = a[1][1].mu(t.a[1][1]);
            return ans;
        }
    }

    static M x;
    static M e;

    static M pow(int t) {
        M ans = e;
        while (t > 0) {
            if ((t & 1) == 1) {
                ans = ans.mu(x);
            }
            x = x.mu(x);
            t >>= 1;
        }
        return ans;
    }

    static Mat ans;

    public static void main(String[] args) {
        x=new M();
        e=new M();
        while(in.hasNext()) {
            int n=in.nextInt(),k=in.nextInt();
            mod=in.nextLong();
            setE(n);setZ(n);setA(n);
            x.set(E, A, Z, A);
            e.set(E, Z, Z, E);
            ans=pow(k).a[0][1];
            for(int i=0;i<n;i++) {
                for(int j=0;j<n;j++) {
                    if(j!=0)System.out.print(" ");
                    System.out.print(ans.a[i][j]);
                }
                System.out.println();
            }
        }
    }
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值