题目链接: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();
}
}
}
}