给出C1,C2以及若干种操作,在C1,C2直接相互赋值加减,或者C1(C2)加某个常数,或者C1(C2)乘某个常数,求最后C2的值。
可以转化成矩阵来做,根据不同的组合可以转化成13种矩阵操作,乘起来之后快速幂即可。
代码写的比较暴力。。
1 #include <stdio.h> 2 #include <string.h> 3 typedef long long LL; 4 const LL MOD = 1000000007; 5 int op[13][3][3]={ 6 { //SET C1,C1,SET C2,C2 7 {1,0,0},{0,1,0},{0,0,1} 8 },{//SET C1 C2 9 {0,1,0},{0,1,0},{0,0,1} 10 },{//SET C2,C1 11 {1,0,0},{1,0,0},{0,0,1} 12 },{//SET C1 N 13 {0,0,9},{0,1,0},{0,0,1} 14 },{//SET C2 N 15 {1,0,0},{0,0,9},{0,0,1} 16 },{//ADD C1 C1 17 {2,0,0},{0,1,0},{0,0,1} 18 },{//ADD C2 C2 19 {1,0,0},{0,2,0},{0,0,1} 20 },{//ADD C1 C2 21 {1,1,0},{0,1,0},{0,0,1} 22 },{//ADD C2 C1 23 {1,0,0},{1,1,0},{0,0,1} 24 },{//ADD C1 N 25 {1,0,9},{0,1,0},{0,0,1} 26 },{//ADD C2 N 27 {1,0,0},{0,1,9},{0,0,1} 28 },{//MUL C1 N 29 {9,0,0},{0,1,0},{0,0,1} 30 },{//MUL C2 N 31 {1,0,0},{0,9,0},{0,0,1} 32 } 33 }; 34 int cas, q; 35 LL v, tu, mat[3][3]; 36 char ss[1000],s1[1000],s2[1000],s3[1000]; 37 struct bign{ 38 int len,s[200]; 39 bign(){memset(s, 0, sizeof s); len=0;} 40 void init(char *ss){ 41 len = strlen(ss); 42 for (int i = len - 1; i >= 0; i--) s[i] = ss[len-1-i]-'0'; 43 } 44 void clean(){while (len>1 && s[len-1] == 0) len--;} 45 void div2(){ 46 int m = 0; 47 for (int i = len - 1; i >= 0; i--) { 48 int k = (s[i] + m * 10) / 2; 49 m = (s[i] + m * 10) % 2; 50 s[i] = k; 51 } 52 clean(); 53 } 54 bool odd(){return s[0] % 2;} 55 bool zero(){return len == 1 && s[0] == 0;} 56 }; 57 58 struct matrix{ 59 LL m[3][3]; 60 matrix(){init(0);} 61 #define For(i,n) for(int i=0;i<n;i++) 62 void init(int t){ 63 memset(m, 0, sizeof m); 64 if (t == 1) m[0][0] = m[1][1] = m[2][2] = 1; 65 else if(t == 2)For(i, 3)For(j, 3)m[i][j] = mat[i][j]; 66 } 67 matrix operator *(const matrix& b) const{ 68 matrix ans; 69 For(i, 3)For(j, 3)For(k, 3)ans.m[i][j] = (ans.m[i][j] + m[i][k] * b.m[k][j]) % MOD; 70 return ans; 71 } 72 matrix binMul(bign b){ 73 matrix ans, tmp; 74 ans.init(1); 75 tmp = *this; 76 for ( ;!b.zero(); b.div2()) { 77 if (b.odd()) {ans = ans * tmp;} 78 tmp = tmp * tmp; 79 } 80 return ans; 81 } 82 }; 83 84 int main(){ 85 scanf("%d", &cas); 86 for (int ca = 1; ca <= cas; ca++) { 87 scanf("%I64d", &v); 88 gets(ss); 89 matrix mt,mt2; mt.init(1); 90 while(gets(ss), strcmp(ss, "END")){ 91 sscanf(ss, "%s %[^,], %s", s1, s2, s3); 92 if(s3[0] != 'C')sscanf(s3, "%I64d", &tu); 93 int id = -1; 94 if(s1[0] == 'S' && strcmp(s2, "C1") == 0 && strcmp(s3, "C1") == 0) id = 0; 95 else if(s1[0] == 'S' && strcmp(s2, "C2") == 0 && strcmp(s3, "C2") == 0) id = 0; 96 else if(s1[0] == 'S' && strcmp(s2, "C1") == 0 && strcmp(s3, "C2") == 0) id = 1; 97 else if(s1[0] == 'S' && strcmp(s2, "C2") == 0 && strcmp(s3, "C1") == 0) id = 2; 98 else if(s1[0] == 'S' && strcmp(s2, "C1") == 0 && strcmp(s3, "C2") != 0) id = 3; 99 else if(s1[0] == 'S' && strcmp(s2, "C2") == 0 && strcmp(s3, "C1") != 0) id = 4; 100 else if(s1[0] == 'A' && strcmp(s2, "C1") == 0 && strcmp(s3, "C1") == 0) id = 5; 101 else if(s1[0] == 'A' && strcmp(s2, "C2") == 0 && strcmp(s3, "C2") == 0) id = 6; 102 else if(s1[0] == 'A' && strcmp(s2, "C1") == 0 && strcmp(s3, "C2") == 0) id = 7; 103 else if(s1[0] == 'A' && strcmp(s2, "C2") == 0 && strcmp(s3, "C1") == 0) id = 8; 104 else if(s1[0] == 'A' && strcmp(s2, "C1") == 0 && strcmp(s3, "C2") != 0) id = 9; 105 else if(s1[0] == 'A' && strcmp(s2, "C2") == 0 && strcmp(s3, "C2") != 0) id = 10; 106 else if(s1[0] == 'M' && strcmp(s2, "C1") == 0 && strcmp(s3, "C2") != 0) id = 11; 107 else if(s1[0] == 'M' && strcmp(s2, "C2") == 0 && strcmp(s3, "C2") != 0) id = 12; 108 109 for(int i = 0; i < 3; i ++)for(int j = 0; j < 3; j++) { 110 mat[i][j] = op[id][i][j] == 9 ? tu : op[id][i][j]; 111 } 112 mt2.init(2); 113 mt = mt2 * mt; 114 } 115 scanf("%d", &q); 116 printf("Case %d:\n", ca); 117 while (q--) { 118 scanf("%s", ss); 119 bign b; b.init(ss); 120 matrix mmt = mt.binMul(b); 121 printf("%I64d\n", (mmt.m[1][0] * v + mmt.m[1][2]) % MOD); 122 } 123 } 124 return 0; 125 }