HDU 4686 Arc of Dream

http://acm.hdu.edu.cn/showproblem.php?pid=4686



多校的第9场比赛,这题是这场比赛中的第一题,似乎是一道签到题,不过,我第一眼看到,深深地表示不会,唯一想到的就是想去寻找它的循环,然后就YY去做它了。好在lele犀利的发现了它是一道矩阵题(表示矩阵做得很少,线代接近白学,orz),然后lele果断敲掉了它。

好吧,赛后在acmood学长的教导下,我自己敲了一个。

思路 : 够造出一个二维矩阵A来,使得A × [ai * bi  ai  bi 1 S(i)]   =   [a(i+1) * b(i+1)   a(i+1)  b(i+1)  1 S(i+1)]来,然后就是对于A矩阵做幂运算(二进制优化下)即可了。


//cnwsycf
//freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);

#include <queue>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>


using namespace std;
typedef __int64 LL;

const int INF = 1<<29;

const int mod = 1000000007;
const int maxn = 1005;

#define MAX(a,b) (a > b ? a : b)
#define MIN(a,b) (a > b ? b : a)

struct node
{
      LL aa[5][5];
}dd[64];

struct diaosi
{
      LL bb[5];
}ans;

bool bit[64];

LL N,a,A,B,b,C,D,M;

void init()
{
      memset(dd,0,sizeof(dd));
      dd[0].aa[0][0] = (A % mod) * (C % mod) % mod;
      dd[0].aa[0][1] = (A % mod) * (D % mod) % mod;
      dd[0].aa[0][2] = (B % mod) * (C % mod) % mod;
      dd[0].aa[0][3] = (B % mod) * (D % mod) % mod;
      dd[0].aa[1][1] = (A % mod);
      dd[0].aa[1][3] = (B % mod);
      dd[0].aa[2][2] = (C % mod);
      dd[0].aa[2][3] = (D % mod);
      dd[0].aa[3][3] = 1;
      dd[0].aa[4][0] = (A % mod) * (C % mod) % mod;
      dd[0].aa[4][1] = (A % mod) * (D % mod) % mod;
      dd[0].aa[4][2] = (B % mod) * (C % mod) % mod;
      dd[0].aa[4][3] = (B % mod) * (D % mod) % mod;
      dd[0].aa[4][4] = 1;
      ans.bb[0] = (a % mod) * (b % mod) % mod;
      ans.bb[1] = a % mod;
      ans.bb[2] = b % mod;
      //for (int i=0;i<4;i++)ans.bb[i] = 1;
      ans.bb[3] = 1;
      ans.bb[4] = ans.bb[0];
      LL tt = N - 1;
      M = 0;
      while (tt > 0)
      {
            bit[M++] = tt % 2;
            tt /= 2;
      }
      return ;
}

void cheng(int x)
{
      //node temp;
      for (int i=0;i<5;i++)
            for (int j=0;j<5;j++)
            {
                  LL sum = 0;
                  for (int k=0;k<5;k++)
                  {
                        sum += (dd[x].aa[i][k] % mod) * (dd[x].aa[k][j] % mod);
                        sum %= mod;
                  }
                  dd[x+1].aa[i][j] = sum;
            }
}

void bitcreate()
{
      for (int i=0;i<M;i++)
      {
            cheng(i);
      }
      //memset(bit,0,sizeof(bit))
      //for (int i=0;i<M;i++)printf("%d",bit[i]);printf("\n");
      return ;
}

void xiangcheng(int x)
{
      diaosi temp;
      for (int i=0;i<5;i++)
      {
            LL sum = 0;
            for (int j=0;j<5;j++)
            {
                  sum += (dd[x].aa[i][j] % mod) * (ans.bb[j] % mod);
                  sum %= mod;
            }
            temp.bb[i] = sum;
      }
      ans = temp;
      //for (int i=0;i<5;i++)printf("%d ",ans.bb[i]);printf("\n");
}

void show()
{
      for (int k=0;k<M;k++)
      {
            for (int i=0;i<5;i++)
            {
                  for (int j=0;j<5;j++)
                        printf("%d ",dd[k].aa[i][j]);
                  printf("\n");
            }
            printf("\n");
      }
}

LL solve()
{
      for (int i=0;i<M;i++)
      {
            if (bit[i])xiangcheng(i);
      }
      return ans.bb[4];
}

int main()
{
      while (scanf("%I64d%I64d%I64d%I64d%I64d%I64d%I64d",&N,&a,&A,&B,&b,&C,&D) != EOF)
      {
            if (N == 0)
            {
                  printf("0\n");
                  continue ;
            }
            init();
            //show();
            bitcreate();
            //show();
            LL sum = solve();
            printf("%d\n",sum % mod);

      }
      return 0;
}


转载于:https://www.cnblogs.com/cnwsycf/p/3335362.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值