UVA 10655 矩阵快速幂

题目链接:https://vjudge.net/problem/UVA-10655
第一次遇到这种终止条件,记录一下。
题目说的是 Input is terminated by a line containing only two zeroes 也就是一行中有且只有两个数 且都为0(不用判) 就终止 ,
不能当p == 0 && q == 0 时就break ,因为0 0 n也是符合条件的输入。
所以循环条件就是 cin >> p >> q >> n 或者 scanf(…) == 3

#include <bits/stdc++.h>
typedef long long ll;
using namespace std;

ll p, q, n, num1, num2;
struct mat {
	ll m[5][5];
}unit;

void init() {
	memset(unit.m, 0, sizeof(unit.m));
	for (int i = 0; i < 2; ++i) 
		unit.m[i][i] = 1;
}
mat operator * (mat a, mat b) {
	mat res;
	for (int i = 0; i < 2; ++i) {
		for (int j = 0; j < 2; ++j) {
			ll x = 0;
			for (int k = 0; k < 2; ++k) {
				x += a.m[i][k] * b.m[k][j];
			}
			res.m[i][j] = x;
		}
	}
	return res;
}
mat power(mat a, ll n) {
	mat res = unit;
	while (n) {
		if (n & 1) res = res * a;
		a = a * a;
		n >>= 1;
	}
	return res;
}
//void check(mat a) {
//	for (int i = 0; i < 2; ++i) {
//		for (int j = 0; j < 2; ++j) {
//			cout << a.m[i][j] << " ";
//		}
//		cout << endl;
//	}
//}

int main() {
	ios::sync_with_stdio(false); cin.tie(0);
	init();
	while (cin >> p >> q >> n) {
		num1 = p;	
		num2 = p*p - 2*q;
		if (n == 0) {
			cout << 2 << '\n';
			continue;
		}
		if (n == 1) {
			cout << num1 << '\n';
			continue;
		}
		if (n == 2) {
			cout << num2 << '\n';
			continue;
		}
		mat a, b;
		a.m[0][0] = num2; a.m[0][1] = num1;
		b.m[0][0] = p; b.m[0][1] = 1;
		b.m[1][0] = -q; b.m[1][1] = 0;
		b = power(b, n-2);
//		check(b);
		mat ans;
		for (int i = 0; i < 1; ++i) {
			for (int j = 0; j < 2; ++j) {
				ll x = 0;
				for (int k = 0; k < 2; ++k) {
					x += a.m[i][k] * b.m[k][j];
				}
				ans.m[i][j] = x;
			}
		}
		cout << ans.m[0][0] << '\n';
	}
	return 0;
} 
发布了51 篇原创文章 · 获赞 6 · 访问量 1667

猜你喜欢

转载自blog.csdn.net/qq_43555854/article/details/100749431