hdu3658 递推 矩阵快速幂

来源:互联网 发布:视频人脸打马赛克软件 编辑:程序博客网 时间:2024/05/21 12:49

解题报告

题目 http://acm.hdu.edu.cn/showproblem.php?pid=3658

 

算法 :递推 +矩阵快速幂

思路 :很明显的递推+矩阵快速幂的题,但比赛是确没写出来,主要有两个原因:

1:设定状态为f[m][k][0] f[m][k][1]表是长度为mk结尾的个数[0]表示不含差值为32的,[1]表示含差值为32

2:数据范围太大,没使用过如此大的矩阵(其实不大)!

 

此题要求至少含一个差值为32,且整体<=32的串.那么至少的反命题是都不,全域是<=32.

应此我们只要求出 <32的串的个数然后用全部的个数减去它即可。

状态 f[m][k] =f[m – 1][j]  (j – k<= 32)

然后构造一个52×52的矩阵即可。

经验与收获 :比赛时有想法就努力去思考,去实现。写代码要细心,变量搞混会很烦的。

提交情况 wrong answer3次(数组用错了)

                     Accepted 1

ACcode

#include <stdio.h>

 

typedef __int64I64;

#define MAXN 52

#define MOD 1000000007

 

struct LINE{

   I64 line[MAXN];

};

 

struct ROW{

   LINE row[MAXN];

};

 

ROW Matrix, temp;

 

ROW Matrix_multi(ROW A, ROW B){

   int i, j, k;

   ROW ans = {0};

   for(i = 0; i < 52; i++)

      for(j = 0; j < 52; j++)

          for(k = 0; k < 52; k++)

             ans.row[i].line[j] = (ans.row[i].line[j] + A.row[i].line[k] *B.row[k].line[j]) % MOD;

   return ans;

}

 

I64 Get_ans(intn){

   int i, j;

   I64 ans = 0;

   for(i = 0; i < 52; i++)

      for(j = 0; j < 52; j++)

          if(i == j) temp.row[i].line[i] =1;

          else temp.row[i].line[j] =0;

   n -= 1;

   while(n){

      if(n & 1) temp =Matrix_multi(temp, Matrix);

      Matrix = Matrix_multi(Matrix, Matrix);

      n >>= 1;

   }

   for(i = 0; i < 52; i++)

      for(j = 0; j < 52; j++)

          ans = (ans +temp.row[i].line[j]) % MOD;

   return ans;

}

 

voidclear(){

   int i, j;

   for(i = 0; i < 52; i++)

      for(j = 0; j < 52; j++)

          Matrix.row[i].line[j] = 0;

}

 

int main(){

   int i, j, CASE, T, n;

   I64 ans1, ans2;

   scanf("%d",&CASE);

   for(T = 1; T <=CASE; T ++){

      scanf("%d",&n);

      clear();

      for(j = 0; j < 52; j++)

          if(j <26){

             for(i = 0; i < 26; i++)

                 Matrix.row[i].line[j] = 1;

             for(i = 26; i < 26 +j + 1; i ++)

                 Matrix.row[i].line[j] = 1;

          }

          else{

             for(i = 26; i < 52;i ++)

                 Matrix.row[i].line[j] = 1;

             for(i = 25; i >= j -26; i --)

                 Matrix.row[i].line[j] = 1;

          }

      ans1 = Get_ans(n);

      clear();

      for(j = 0; j < 52; j++)

          if(j <26){

             for(i = 0; i < 26; i++)

                 Matrix.row[i].line[j] = 1;

             for(i = 26; i < 26 +j; i ++)

                 Matrix.row[i].line[j] = 1;

          }

          else{

             for(i = 26; i < 52;i ++)

                 Matrix.row[i].line[j] = 1;

             for(i = 25; i > j -26; i --)

                 Matrix.row[i].line[j] = 1;

          }

      ans2 = Get_ans(n);

      printf("%I64d\n", ((ans1 - ans2)% MOD + MOD) % MOD);

   }

   return 0;

}