#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
const int MSZ = 3;
struct Mat {
int d[MSZ][MSZ];
Mat() {
memset(d, 0, sizeof d);
for (int i = 0; i < MSZ; i++)
d[i][i] = 1;
}
void operator*=(const Mat &m2) {
int res[MSZ][MSZ];
memset(res, 0, sizeof res);
for (int i = 0; i < MSZ; i++)
for (int j = 0; j < MSZ; j++)
for (int k = 0; k < MSZ; k++)
res[i][j] += d[i][k] * m2.d[k][j];
memcpy(d, res, sizeof d);
}
};
Mat pow1(Mat a, int b) {
Mat res;
for (; b; b >>= 1, a *= a)
if (b & 1) res *= a;
return res;
}
Mat pow2(Mat a, int b) {
if (b == 0) return Mat();
if (b & 1) {
Mat res = pow2(a, b - 1);
res *= a;
return res;
}
Mat res = pow2(a, b >> 1);
res *= res;
return res;
}
const int POW = 1e9;
const int STEPS = 3e5;
int main() {
Mat src;
for (int i = 0; i < MSZ; i++)
for (int j = 0; j < MSZ - i; j++)
src.d[i][j] = 1;
clock_t st = clock();
for (int step = 0; step < STEPS; step++)
pow1(src, POW);
printf("%d\n", clock() - st);
st = clock();
for (int step = 0; step < STEPS; step++)
pow2(src, POW);
printf("%d\n", clock() - st);
return 0;
}
I2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8dGltZS5oPgoKY29uc3QgaW50IE1TWiA9IDM7CgpzdHJ1Y3QgTWF0IHsKICBpbnQgZFtNU1pdW01TWl07CgogIE1hdCgpIHsKICAgIG1lbXNldChkLCAwLCBzaXplb2YgZCk7CiAgICBmb3IgKGludCBpID0gMDsgaSA8IE1TWjsgaSsrKQogICAgICBkW2ldW2ldID0gMTsKICB9CgogIHZvaWQgb3BlcmF0b3IqPShjb25zdCBNYXQgJm0yKSB7CiAgICBpbnQgcmVzW01TWl1bTVNaXTsKICAgIG1lbXNldChyZXMsIDAsIHNpemVvZiByZXMpOwogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBNU1o7IGkrKykKICAgIGZvciAoaW50IGogPSAwOyBqIDwgTVNaOyBqKyspCiAgICBmb3IgKGludCBrID0gMDsgayA8IE1TWjsgaysrKQogICAgICByZXNbaV1bal0gKz0gZFtpXVtrXSAqIG0yLmRba11bal07CiAgICBtZW1jcHkoZCwgcmVzLCBzaXplb2YgZCk7CiAgfQp9OwoKTWF0IHBvdzEoTWF0IGEsIGludCBiKSB7CiAgTWF0IHJlczsKICBmb3IgKDsgYjsgYiA+Pj0gMSwgYSAqPSBhKQogICAgaWYgKGIgJiAxKSByZXMgKj0gYTsKICByZXR1cm4gcmVzOwp9CgpNYXQgcG93MihNYXQgYSwgaW50IGIpIHsKICBpZiAoYiA9PSAwKSByZXR1cm4gTWF0KCk7CiAgaWYgKGIgJiAxKSB7CiAgICBNYXQgcmVzID0gcG93MihhLCBiIC0gMSk7CiAgICByZXMgKj0gYTsKICAgIHJldHVybiByZXM7CiAgfQogIE1hdCByZXMgPSBwb3cyKGEsIGIgPj4gMSk7CiAgcmVzICo9IHJlczsKICByZXR1cm4gcmVzOwp9Cgpjb25zdCBpbnQgUE9XID0gMWU5Owpjb25zdCBpbnQgU1RFUFMgPSAzZTU7CgppbnQgbWFpbigpIHsKICBNYXQgc3JjOwogIGZvciAoaW50IGkgPSAwOyBpIDwgTVNaOyBpKyspCiAgZm9yIChpbnQgaiA9IDA7IGogPCBNU1ogLSBpOyBqKyspCiAgICBzcmMuZFtpXVtqXSA9IDE7CiAgCiAgY2xvY2tfdCBzdCA9IGNsb2NrKCk7CiAgZm9yIChpbnQgc3RlcCA9IDA7IHN0ZXAgPCBTVEVQUzsgc3RlcCsrKQogICAgcG93MShzcmMsIFBPVyk7CiAgcHJpbnRmKCIlZFxuIiwgY2xvY2soKSAtIHN0KTsKCiAgc3QgPSBjbG9jaygpOwogIGZvciAoaW50IHN0ZXAgPSAwOyBzdGVwIDwgU1RFUFM7IHN0ZXArKykKICAgIHBvdzIoc3JjLCBQT1cpOwogIHByaW50ZigiJWRcbiIsIGNsb2NrKCkgLSBzdCk7ICAKICByZXR1cm4gMDsKfQo=