#include <assert.h>
#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(const Mat &a, int b) {
if (b == 0) {
return Mat();
}
Mat res = pow2(a, b >> 1);
res *= res;
if (b & 1) {
res *= a;
}
return res;
}
const int POW = (1 << 30) - 1;
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;
Mat res;
clock_t st = clock();
for (int step = 0; step < STEPS; step++)
res = pow1(src, POW);
printf("%d\n", clock() - st);
st = clock();
Mat res2;
for (int step = 0; step < STEPS; step++)
res2 = pow2(src, POW);
printf("%d\n", clock() - st);
for (int i = 0; i < MSZ; i++)
for (int j = 0; j < MSZ; j++)
assert(res.d[i][j] == res2.d[i][j]);
return 0;
}
I2luY2x1ZGUgPGFzc2VydC5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDx0aW1lLmg+Cgpjb25zdCBpbnQgTVNaID0gMzsKCnN0cnVjdCBNYXQgewogIGludCBkW01TWl1bTVNaXTsKCiAgTWF0KCkgewogICAgbWVtc2V0KGQsIDAsIHNpemVvZiBkKTsKICAgIGZvciAoaW50IGkgPSAwOyBpIDwgTVNaOyBpKyspCiAgICAgIGRbaV1baV0gPSAxOwogIH0KCiAgdm9pZCBvcGVyYXRvcio9KGNvbnN0IE1hdCAmbTIpIHsKICAgIGludCByZXNbTVNaXVtNU1pdOwogICAgbWVtc2V0KHJlcywgMCwgc2l6ZW9mIHJlcyk7CiAgICBmb3IgKGludCBpID0gMDsgaSA8IE1TWjsgaSsrKQogICAgZm9yIChpbnQgaiA9IDA7IGogPCBNU1o7IGorKykKICAgIGZvciAoaW50IGsgPSAwOyBrIDwgTVNaOyBrKyspCiAgICAgIHJlc1tpXVtqXSArPSBkW2ldW2tdICogbTIuZFtrXVtqXTsKICAgIG1lbWNweShkLCByZXMsIHNpemVvZiBkKTsKICB9Cn07CgpNYXQgcG93MShNYXQgYSwgaW50IGIpIHsKICBNYXQgcmVzOwogIGZvciAoOyBiOyBiID4+PSAxLCBhICo9IGEpCiAgICBpZiAoYiAmIDEpIHJlcyAqPSBhOwogIHJldHVybiByZXM7Cn0KCk1hdCBwb3cyKGNvbnN0IE1hdCAmYSwgaW50IGIpIHsKICAgIGlmIChiID09IDApIHsKICAgICAgICByZXR1cm4gTWF0KCk7CiAgICB9CiAgICBNYXQgcmVzID0gcG93MihhLCBiID4+IDEpOwogICAgcmVzICo9IHJlczsKICAgIGlmIChiICYgMSkgewogICAgICAgIHJlcyAqPSBhOwogICAgfQogICAgcmV0dXJuIHJlczsKfQoKY29uc3QgaW50IFBPVyA9ICgxIDw8IDMwKSAtIDE7CmNvbnN0IGludCBTVEVQUyA9IDNlNTsKCmludCBtYWluKCkgewogIE1hdCBzcmM7CiAgZm9yIChpbnQgaSA9IDA7IGkgPCBNU1o7IGkrKykKICBmb3IgKGludCBqID0gMDsgaiA8IE1TWiAtIGk7IGorKykKICAgIHNyYy5kW2ldW2pdID0gMTsKICAKICBNYXQgcmVzOwogIGNsb2NrX3Qgc3QgPSBjbG9jaygpOwogIGZvciAoaW50IHN0ZXAgPSAwOyBzdGVwIDwgU1RFUFM7IHN0ZXArKykKICAgIHJlcyA9IHBvdzEoc3JjLCBQT1cpOwogIHByaW50ZigiJWRcbiIsIGNsb2NrKCkgLSBzdCk7CgogIHN0ID0gY2xvY2soKTsKICBNYXQgcmVzMjsKICBmb3IgKGludCBzdGVwID0gMDsgc3RlcCA8IFNURVBTOyBzdGVwKyspCiAgICByZXMyID0gcG93MihzcmMsIFBPVyk7CiAgcHJpbnRmKCIlZFxuIiwgY2xvY2soKSAtIHN0KTsKCiAgZm9yIChpbnQgaSA9IDA7IGkgPCBNU1o7IGkrKykKICBmb3IgKGludCBqID0gMDsgaiA8IE1TWjsgaisrKQogICAgYXNzZXJ0KHJlcy5kW2ldW2pdID09IHJlczIuZFtpXVtqXSk7CiAgcmV0dXJuIDA7Cn0K