zoukankan      html  css  js  c++  java
  • 20191216 GXOI 2019模拟赛 逼死强迫症

    题目传送门

    分析:

    sb矩阵加速推一辈子。。。

    想了1个小时,结果好像还和标准答案的方法不一样诶。。。

    标算解法:

    老套路,对于新加入的一列,考虑它与目前最后一列的关系

    我们可以列出四种方案:

    其中前两种我们知道一定使用了一个小块

    但是后面两种就不知道是用过还是没用过了,用了就一定用了两个

    所以再枚举两个状态0/1,表示用了或没用

    然后就有了6个状态。。。

    这6个状态可以互相胡乱转移一通,然后就可以得出答案2333

    具体怎么转移其实不难,然后说一说自己的口胡写法2333

    胡乱解法(自己的):

    老套路,考虑新加入一行(假设两个碎块在前面已经用过)

    此时考虑竖放和横放就是g ( i - 1 ) + g ( i - 2 )

    然后考虑碎块放最后。。。

    当确定两个碎块的间距后和相对位置时,摆放方式也就确定了

    然后我们假设最后放的是包含碎块的几列,当列数为 j 时,前面的方案数就为Fib( i - j )

    那么枚举 j 后的总方案就是SumFib ( i - 3 ) ,因为碎块长度最小为3

    所以

    g ( i ) = g ( i - 1 ) + g ( i - 2 ) + 2 * SumFib ( i - 3 )

    前缀和我们推一下式子得到:

    SumFib ( i ) = 2 * SumFib ( i - 1 ) - SumFib ( i - 3 )

    然后这里有6个关键值,我们可以用5*5的矩阵维护

     字很烂,原谅一下哈哈哈嗝。。。

    然后矩阵加速就好了。。。

    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    
    #define maxn 100005
    #define MOD 1000000007
    
    using namespace std;
    
    inline int getint()
    {
        int num=0,flag=1;char c;
        while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;
        while(c>='0'&&c<='9')num=num*10+c-48,c=getchar();
        return num*flag;
    }
    
    struct node{
        long long a[5][5];
        friend node operator *(node x,node y)
        {
            node z;memset(z.a,0,sizeof z.a);
            for(int i=0;i<5;i++)for(int j=0;j<5;j++)for(int k=0;k<5;k++)
                (z.a[i][j]+=x.a[i][k]*y.a[k][j])%=MOD;
            return z;
        }
    }tr,I,A;
    int P[5][5]={{1,1,0,0,0},{1,0,0,0,0},{2,0,2,1,0},{0,0,0,0,1},{0,0,MOD-1,0,0}};
    
    inline node ksm(node num,int k)
    {
        node ret=I;
        for(;k;k>>=1,num=num*num)if(k&1)ret=ret*num;
        return ret;
    }
    
    int main()
    {
        int T=getint();
        for(int i=0;i<5;i++)I.a[i][i]=1;
        for(int i=0;i<5;i++)for(int j=0;j<5;j++)tr.a[i][j]=P[i][j];
        A.a[0][0]=2,A.a[0][2]=2,A.a[0][3]=1;
        while(T--)
        {
            int n=getint()-3;
            if(n<0){printf("0
    ");continue;}
            node tmp=A*ksm(tr,n);
            printf("%lld
    ",tmp.a[0][0]);
        }
    }
    View Code

  • 相关阅读:
    vue-element-admin项目install出现的问题
    关于html5 Notification桌面通知无法在谷歌浏览器显示的问题
    C#调用存储过程执行缓慢,但在数据库中执行却很快的问题
    IdnentiyServer-使用客户端凭据访问API
    IdentityServer开题篇
    IdentityServer4客户端JWT解密实现(基于.net4.0)
    iis访问网络路径映射问题(UNC share)
    .net core部署在iis上
    git blame 查找修改者
    代码管理工具-将项目文件打成tar包,并且排除.git目录
  • 原文地址:https://www.cnblogs.com/Darknesses/p/12051127.html
Copyright © 2011-2022 走看看