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;
} 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章