二次联通门 : luogu P1939 【模板】矩阵加速(数列)
/* luogu P1939 【模板】矩阵加速(数列) 模板题不说什么
许久不写代码。。
感觉好别扭
*/ #include <cstring> #include <cstdio> #define Mod 1000000007 void read (long long &now) { now = 0; register char word = getchar (); while (word < '0' || word > '9') word = getchar (); while (word >= '0' && word <= '9') { now = now * 10 + word - '0'; word = getchar (); } } struct Martix { static const int _L = 3; long long data[_L][_L]; Martix operator * (const Martix &now) const { Martix res; for (register int i = 0, j, k; i < _L; i ++) for (j = 0; j < _L; j ++) { res.data[i][j] = 0; for (k = 0; k < _L; k ++) res.data[i][j] = (res.data[i][j] + this->data[i][k] * now.data[k][j]) % Mod; } return res; } void Fill () { for (register int i = 0, j; i < _L; i ++) for (j = 0; j < _L; j ++) this->data[i][j] = 0; this->data[0][2] = 1; this->data[1][0] = 1; this->data[2][1] = 1; this->data[2][2] = 1; } }; Martix operator ^ (Martix now, long long P) { Martix Answer; memset (Answer.data, 0, sizeof Answer.data); Answer.data[0][0] = 1; Answer.data[1][1] = 1; Answer.data[2][2] = 1; for (; P; P >>= 1) { if (P & 1) Answer = Answer * now; now = now * now; } return Answer; } long long N; int main (int argc, char *argv[]) { long long T; Martix A; for (read (T); T --; ) { read (N); if (N <= 3 && N > 0) { putchar ('1'); putchar (' '); continue; } else if (N <= 0) { putchar ('0'); putchar (' '); continue; } N -= 3; A.Fill (); A = A ^ N; printf ("%lld ", (A.data[2][0] + A.data[2][1] + A.data[2][2]) % Mod); } return 0; }