HDU 4382 Harry Potter and Cyber Sequence Generator [矩阵乘法]

  给出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 }
posted @ 2012-10-04 01:30  Burn_E  阅读(300)  评论(0编辑  收藏  举报