-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathitrix12e.cpp
134 lines (124 loc) · 3.31 KB
/
itrix12e.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#include "vector"
#include "algorithm"
#include "iostream"
#include "cmath"
#include <thread>
using namespace std;
typedef long long ll;
typedef vector<ll> vll;
typedef vector<vll> vvll;
vll primes{2,3,5,7,11,13,17,19},sum = {0,4};
vvll pairs(9, vll(9));
vll dp(9,0);
vvll inv = {{1,1,0,-1,0,-1,-2,0,0},
{1,1,0,0,-1,-1,-1,-1,0},
{0,0,0,-1,1,1,0,0,-1},
{-1,0,-1,-2,3,2,0,1,-1},
{0,-1,1,3,-3,-2,1,-1,1},
{-1,-1,1,2,-2,-1,1,0,1},
{-2,-1,0,0,1,1,2,1,0},
{0,-1,0,1,-1,0,1,0,0},
{0,0,-1,-1,1,1,0,0,0}
};
vvll eye = {
{1,0,0,0,0,0,0,0,0},
{0,1,0,0,0,0,0,0,0},
{0,0,1,0,0,0,0,0,0},
{0,0,0,1,0,0,0,0,0},
{0,0,0,0,1,0,0,0,0},
{0,0,0,0,0,1,0,0,0},
{0,0,0,0,0,0,1,0,0},
{0,0,0,0,0,0,0,1,0},
{0,0,0,0,0,0,0,0,1}
};
void calc_pairs(ll x, vvll& pairs){
for(ll i = 0; i < 9; i++){
if(find(primes.begin(), primes.end(), i+x+2) != primes.end()) {
pairs[i][x] = 1;
}
}
}
ll modulo(ll n){
if(n >= 0) return n % 1000000007;
else{
return 1000000007 + n % 1000000007;
}
}
void init(){
dp[1] = dp[2] = dp[4] = dp[6] = 1;
for(ll i = 2; i <= 2; i++){
vll dp_old(dp);
sum.push_back(sum[i-1]);
for(ll j = 0; j < 9; j++){
dp[j] = 0;
for(ll k = 0; k < 9; k++){
if(pairs[j][k] == 1) {
dp[j] += max(dp_old[k], ll(1));
dp[j] %= 1000000007;
}
}
sum[i] += dp[j];
sum[i] %= 1000000007;
}
}
}
vvll matrix_mul(const vvll &A, const vvll &B)
{
vvll c(A);
for(ll i = 0; i < A.size(); i++){
for(ll j = 0; j < A.size(); j++){
c[i][j] = 0;
for(ll k = 0; k < A.size(); k++) {
c[i][j] = modulo(c[i][j] + modulo(modulo(A[i][k]) * modulo(B[k][j])));
}
}
}
return c;
}
vvll matrix_diff(const vvll &A, const vvll &B){
vvll C(A);
for(ll i = 0; i < A.size(); i++){
for(ll j = 0; j < A.size(); j++) {
C[i][j] = modulo(A[i][j] - B[i][j]);
}
}
return C;
}
vvll log_mul(const vvll& A, ll n){
if(n == 0) return eye;
else if(n == 1) return A;
else if(n == 2) return matrix_mul(A,A);
vvll B = log_mul(A, n / 2);
if(n % 2 == 0) {
return matrix_mul(B,B);
}
else{
vvll C = matrix_mul(B,B);
return matrix_mul(C,A);
}
}
int main(){
for(ll i = 0; i < 9; i++){
calc_pairs(i, pairs);
}
init();
ll t = 0;
vvll DP;
for(ll i = 0; i < 9; i++) DP.push_back(dp); //Store dp[2]
cin >> t;
while(t--){
ll n;
cin >> n;
if(n <= 2) cout << sum[n] << endl;
else{
vvll p_n = log_mul(pairs, n - 1); //Calculate pairs^n-1
p_n = matrix_mul(inv, matrix_diff(eye,p_n)); //Calculate geometric sum till pairs^n
p_n = matrix_mul(DP,p_n); //Calculate dp[n]
ll suml = sum[1];
for(ll i = 0; i < 9; i++) {
suml = modulo(suml + p_n[0][i]);
}
cout << suml << endl;
}
}
}