zoukankan      html  css  js  c++  java
  • fuzhou 1683 纪念SlingShot ***

    Problem 1683 纪念SlingShot

    Accept: 361    Submit: 1287
    Time Limit: 1000 mSec    Memory Limit : 32768 KB

    Problem Description

    已知 F(n)=3 * F(n-1)+2 * F(n-2)+7 * F(n-3),n>=3,其中F(0)=1,F(1)=3,F(2)=5,对于给定的每个n,输出F(0)+ F(1)+ …… + F(n) mod 2009。

    Input

    第一行是一整数m,代表总共有m个cases。

    Output

    对于每个case,输出一行。格式见样例,冒号后有一个空格。

    Sample Input

    2 3 6

    Sample Output

    Case 1: 37 Case 2: 313

    Source

    FOJ月赛-2009年2月- Coral
     
    题意不看,刚开始觉得好水。直接快速幂就可以做。
    后来发现求和的,囧...
    ————————————————————————————
     
      1 /*
      2 矩阵构造:
      3 假设前N项和为S(n), 那么可以推出 S(n)=S(n-1)+f(n);
      4 得到一个矩阵:
      5 
      6 | 1 1 0 0 | | s(n-1) |   |  S(n)  |
      7 | 0 3 2 7 | |  f(n)  | = | f(n+1) |
      8 | 0 1 0 0 | | f(n-1) |   |  f(n)  |
      9 | 0 0 1 0 | | f(n-2) |   | f(n-1) |
     10 
     11 然后每一个N,一次快速幂,过了?额,下面就是这样的代码
     12 超时ing...
     13 
     14 那么就要优化了。优化:题目中矩阵是不变的,只是单纯的问
     15 n的值。保存2^i的结果。每一个数字都能由2^i组成。(二进制优化)
     16 
     17 这样就节省了很多的时间。
     18 484 ms
     19 
     20 特别注意:
     21 在最初的编写过程中,我只是用 (M_tom.mat[1][1]*4+M_tom.mat[1][2]*5)%mod;
     22 这样做的结果是答案偏小了。问题在于还要加上 (M_tom.mat[1][3]*3+M_tom.mat[1][4]*1);
     23 这就是数学的问题了.....囧
     24 动手试一试
     25 */
     26 
     27 /*
     28 #include<iostream>
     29 #include<cstdio>
     30 #include<cstring>
     31 #include<cstdlib>
     32 using namespace std;
     33 typedef __int64 LL;
     34 const __int64 mod=2009;
     35 
     36 struct Matrix
     37 {
     38     LL mat[6][6];
     39     void ini()
     40     {
     41         memset(mat,0,sizeof(mat));
     42     }
     43     void first_ini()
     44     {
     45         for(LL i=1;i<=4;i++)
     46         for(LL j=1;j<=4;j++)
     47         if(i==j) mat[i][j]=1;
     48         else mat[i][j]=0;
     49     }
     50 }M_hxl,M_tom;
     51 
     52 
     53 void make_first()
     54 {
     55     M_hxl.mat[1][1]=1;M_hxl.mat[1][2]=1;M_hxl.mat[1][3]=0;M_hxl.mat[1][4]=0;
     56     M_hxl.mat[2][1]=0;M_hxl.mat[2][2]=3;M_hxl.mat[2][3]=2;M_hxl.mat[2][4]=7;
     57     M_hxl.mat[3][1]=0;M_hxl.mat[3][2]=1;M_hxl.mat[3][3]=0;M_hxl.mat[3][4]=0;
     58     M_hxl.mat[4][1]=0;M_hxl.mat[4][2]=0;M_hxl.mat[4][3]=1;M_hxl.mat[4][4]=0;
     59 }
     60 
     61 Matrix Multiply(Matrix cur,Matrix now)
     62 {
     63     Matrix ww;
     64     ww.ini();
     65     for(LL i=1;i<=4;i++)
     66     for(LL k=1;k<=4;k++)
     67     if(cur.mat[i][k])
     68     {
     69         for(LL j=1;j<=4;j++)
     70         if(now.mat[k][j])
     71         {
     72             ww.mat[i][j]+=cur.mat[i][k]*now.mat[k][j];
     73             if(ww.mat[i][j]>=mod)
     74             ww.mat[i][j]%=mod;
     75         }
     76     }
     77     return ww;
     78 }
     79 
     80 void power_sum2(LL n)
     81 {
     82       M_tom.first_ini();
     83       while(n)
     84       {
     85           if(n&1)
     86           {
     87               M_tom=Multiply(M_hxl,M_tom);
     88           }
     89           n=n>>1;
     90           M_hxl=Multiply(M_hxl,M_hxl);
     91       }
     92       LL sum=0;
     93       sum=(sum+M_tom.mat[1][1]*4)%mod;
     94       sum=(sum+M_tom.mat[1][2]*5)%mod;
     95       sum=(sum+M_tom.mat[1][3]*3)%mod;//!!!开始时没有加
     96       sum=(sum+M_tom.mat[1][4]*1)%mod;//!!!开始时没有加
     97       printf("%I64d
    ",sum);
     98 }
     99 
    100 int main()
    101 {
    102     LL T,n,i;
    103     while(scanf("%I64d",&T)>0)
    104     {
    105         for(i=1;i<=T;i++)
    106         {
    107             scanf("%I64d",&n);
    108             printf("Case %I64d: ",i);
    109             if(n==0)printf("1
    ");
    110             else if(n==1) printf("4
    ");
    111             else if(n==2) printf("9
    ");
    112             else
    113             {
    114                 make_first();
    115                 power_sum2(n-1);
    116             }
    117         }
    118     }
    119     return 0;
    120 }
    121 
    122 
    123 */
    124 
    125 #include<iostream>
    126 #include<cstdio>
    127 #include<cstring>
    128 #include<cstdlib>
    129 using namespace std;
    130 typedef __int64 LL;
    131 const __int64 mod=2009;
    132 
    133 struct Matrix
    134 {
    135     LL mat[6][6];
    136     void ini()
    137     {
    138         memset(mat,0,sizeof(mat));
    139     }
    140     void first_ini()
    141     {
    142         for(LL i=1;i<=4;i++)
    143         for(LL j=1;j<=4;j++)
    144         if(i==j) mat[i][j]=1;
    145         else mat[i][j]=0;
    146     }
    147     void init()
    148     {
    149         mat[1][1]=1;mat[1][2]=1;mat[1][3]=0;mat[1][4]=0;
    150         mat[2][1]=0;mat[2][2]=3;mat[2][3]=2;mat[2][4]=7;
    151         mat[3][1]=0;mat[3][2]=1;mat[3][3]=0;mat[3][4]=0;
    152         mat[4][1]=0;mat[4][2]=0;mat[4][3]=1;mat[4][4]=0;
    153     }
    154 }M_hxl[40],M_tom;
    155 
    156 Matrix Multiply(Matrix cur,Matrix now)
    157 {
    158     Matrix ww;
    159     ww.ini();
    160     for(LL i=1;i<=4;i++)
    161     for(LL k=1;k<=4;k++)
    162     if(cur.mat[i][k])
    163     {
    164         for(LL j=1;j<=4;j++)
    165         if(now.mat[k][j])
    166         {
    167             ww.mat[i][j]+=cur.mat[i][k]*now.mat[k][j];
    168             if(ww.mat[i][j]>=mod)
    169             ww.mat[i][j]%=mod;
    170         }
    171     }
    172     return ww;
    173 }
    174 
    175 void power_sum2(LL n)
    176 {
    177       M_tom.first_ini();//!!
    178       LL cnt=0;
    179       while(n)
    180       {
    181           if(n&1)
    182           {
    183               M_tom=Multiply(M_hxl[cnt],M_tom);
    184           }
    185           n=n>>1;
    186           cnt++;//模拟二进制.
    187       }
    188       LL sum=0;
    189       sum=(sum+M_tom.mat[1][1]*4)%mod;
    190       sum=(sum+M_tom.mat[1][2]*5)%mod;
    191       sum=(sum+M_tom.mat[1][3]*3)%mod;//!!!开始时没有加
    192       sum=(sum+M_tom.mat[1][4]*1)%mod;//!!!开始时没有加
    193       printf("%I64d
    ",sum);
    194 }
    195 
    196 void pripare()
    197 {
    198     LL i;
    199     M_hxl[0].init();
    200     for(i=1;i<32;i++)
    201     M_hxl[i]=Multiply(M_hxl[i-1],M_hxl[i-1]);
    202 }
    203 
    204 int main()
    205 {
    206     LL T,n,i;
    207     pripare();//打表。
    208     while(scanf("%I64d",&T)>0)
    209     {
    210         for(i=1;i<=T;i++)
    211         {
    212             scanf("%I64d",&n);
    213             printf("Case %I64d: ",i);
    214             if(n==0)printf("1
    ");
    215             else if(n==1) printf("4
    ");
    216             else if(n==2) printf("9
    ");
    217             else
    218             {
    219                 power_sum2(n-1);
    220             }
    221         }
    222     }
    223     return 0;
    224 }
  • 相关阅读:
    PTA 两个有序链表序列的合并
    PTA 递增的整数序列链表的插入
    PTA 链表逆置
    PTA 带头结点的链式表操作集
    _KPCR, _NT_TIB, _KPRCB
    FSOP
    逆向PspCreateProcess
    寒假训练 [GKCTF2020]Domo(4/250) 劫持vtable
    IO_FILE利用与劫持vtables控制程序流程、FSOP
    线程结构
  • 原文地址:https://www.cnblogs.com/tom987690183/p/3289399.html
Copyright © 2011-2022 走看看