洛谷OJ固然算是好地方,nodgd同窗打算和朋友分享一下。因而他就拉上了他的朋友Ciocio和Nicole兩位同窗一塊兒刷題。喜歡比賽的他們固然不放過這樣一次刷題比賽的機會!node
在第1天nodgd,Coicoi,Nicole都只作了1道題。c++
在第2天nodgd,Coicoi,Nicole都只作了3道題。git
他們都有着嚴格的刷題規則,而且會在每一天都很遵照規則的刷必定量的題。this
(1)nodgd同窗第k+2天刷題數量a[k+2]=p*a[k+1]+q*a[k]+b[k+1]+c[k+1]+r*k^2+t*k+1;spa
(2)Ciocio同窗第k+2天刷題數量b[k+2]=u*b[k+1]+v*b[k]+a[k+1]+c[k+1]+w^k;code
(3)Nicole同窗第k+2天刷題數量c[k+2]=x*c[k+1]+y*c[k]+a[k+1]+b[k+1]+z^k+k+2;blog
(以上的字母p,q,r,t,u,v,w,x,y,z都是給定的常數,並保證是正整數)ci
因而他們開始了長時間的刷題比賽!一共進行了N天(4<=N<=10^16)get
可是時間是難得的,nodgd想快速知道第N天每一個人的刷題數量。不過nodgd同窗還有大量的數學競賽題、物理競賽題、英語競賽題、美術競賽題、體育競賽題……要作,就拜託你來幫他算算了。數學
因爲結果很大,輸出結果mod K的值便可。
第一行兩個正整數N,K。(4<=N<=10^16,2<=K<=10^16)
第二行四個正整數p,q,r,t。
第三行三個正整數u,v,w。
第四行三個正整數x,y,z。
(保證p,q,r,t,u,v,w,x,y,z都是不超過100的正整數)
共三行,每行一個名字+一個空格+一個整數。依次是nodgd,Ciocio,Nicole和他們在第N天刷題數量mod K的值。
4 10007 2 1 1 1 2 2 3 1 1 2
nodgd 74 Ciocio 80 Nicole 59
矩陣乘法。
注意,中間相乘過程可能會比64位長整型的數據範圍還要大。
#include<bits/stdc++.h> #define LL long long LL in() { char ch; LL x = 0, f = 1; while(!isdigit(ch = getchar()))(ch == '-') && (f = -f); for(x = ch ^ 48; isdigit(ch = getchar()); x = (x << 1) + (x << 3) + (ch ^ 48)); return x * f; } LL n, mod; LL msc(LL x, LL y) { LL re = 0; while(y) { if(y & 1) re = (re + x) % mod; x = (x + x) % mod; y >>= 1; } return re; } struct node { LL ju[15][15]; node() { memset(ju, 0, sizeof ju); } void e() { memset(ju, 0, sizeof ju); for(int i = 1; i <= 11; i++) ju[i][i] = 1; } friend node operator * (const node &a, const node &b) { node t; for(int i = 1; i <= 11; i++) for(int j = 1; j <= 11; j++) for(int k = 1; k <= 11; k++) (t.ju[i][j] += msc(a.ju[i][k], b.ju[k][j])) %= mod; return t; } node ksm(LL y) { node re, x = *this; re.e(); while(y) { if(y & 1) re = re * x; x = x * x; y >>= 1; } return re; } }beg, A; int tmp[12][12] = { {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 1, 0, 2, 1, 0, 0, 0}, {0, 1, 0, 0, 0, 2, 0, 1, 1, 1, 0, 0}, {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, }; int lsbeg[] = {0, 3, 1, 3, 1, 3, 1, 1, 1, 1, 0, 0}; int main() { n = in(), mod = in(); LL w, z; tmp[1][1] = in(); //p tmp[2][1] = in(); //q tmp[7][1] = in(); //r tmp[8][1] = in(); //t tmp[3][3] = in(); //u tmp[4][3] = in(); //v w = tmp[10][10] = in();//w tmp[5][5] = in(); //x tmp[6][5] = in(); //y z = tmp[11][11] = in();//z lsbeg[10] = w, lsbeg[11] = z; for(int i = 1; i <= 11; i++) beg.ju[1][i] = lsbeg[i]; for(int i = 1; i <= 11; i++) for(int j = 1; j <= 11; j++) A.ju[i][j] = tmp[i][j]; beg = beg * A.ksm(n - 2); printf("nodgd %lld\nCiocio %lld\nNicole %lld\n", beg.ju[1][1], beg.ju[1][3], beg.ju[1][5]); return 0; }