• [LOJ3086] [GXOI2019] 逼死强迫症


    题目链接

    LOJ:https://loj.ac/problem/3086

    洛谷:https://www.luogu.org/problemnew/show/P5303

    Solution

    显然不考虑(1 imes 1)的矩形就是斐波那契数列,设为(g),则(g_n=g_{n-1}+g_{n-2})

    设考虑的方案数为(f),那么可以枚举放哪里得到一个暴力式子:

    [egin{align}f_n&=2sum_{i=1}^{n}sum_{j=i+2}^{n}g_{i-1}cdot g_{n-j}\ f_n&=2sum_{i=1}^{n}g_{i-1}sum_{j=i+2}^{n}g_{n-j}\ f_n&=2sum_{j=3}^{n}g_{n-j}sum_{i=1}^{j-2}g_{i-1}\ f_n&=2sum_{j=3}^{n}g_{n-j}s_{j-3} end{align} ]

    (s)(g)的前缀和。

    然后我们考虑(f_{n+1})用已知量凑出来:

    [egin{align} frac{1}{2}f_{n+1}&=sum_{i=3}^{n+1}g_{n+1-i}s_{i-3}\ frac{1}{2}f_{n+1}&=s_{n-2}+s_{n-3}+sum_{i=3}^{n-1}g_{n+1-i}s_{i-3}\ frac{1}{2}f_{n+1}&=s_{n-2}+s_{n-3}+sum_{i=3}^{n-1}(g_{n-i}+g_{n-i-1})s_{i-3}\ frac{1}{2}f_{n+1}&=s_{n-2}+s_{n-3}+sum_{i=3}^{n}g_{n-i}s_{i-3}-s_{n-3}+sum_{i=3}^{n-1}g_{n-i-1}s_{i-3}\ f_{n+1}&=2s_{n-2}+f_n+f_{n-1} end{align} ]

    其实到这里已经可以矩阵维护了,但是那样矩阵会设的很大,对于前缀和我们考虑如何递推:

    [s_n=2+sum_{i=2}^{n}g_i=2+sum_{i=2}^{n}g_{i-1}+g_{i-2}=s_{n-1}+s_{n-2}+1 ]

    那么变一下就是:

    [s_n=s_{n+2}-s_{n-1}-1=g_{n+2}-1 ]

    那么我们只需要开(5 imes 5)的矩阵维护就好了,复杂度(O(125Tlog n))

    #include<bits/stdc++.h>
    using namespace std;
    
    void read(int &x) {
        x=0;int f=1;char ch=getchar();
        for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-f;
        for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';x*=f;
    }
    
    void print(int x) {
        if(x<0) putchar('-'),x=-x;
        if(!x) return ;print(x/10),putchar(x%10+48);
    }
    void write(int x) {if(!x) putchar('0');else print(x);putchar('
    ');}
    
    #define lf double
    #define ll long long 
    
    #define pii pair<int,int >
    #define vec vector<int >
    
    #define pb push_back
    #define mp make_pair
    #define fr first
    #define sc second
    
    #define FOR(i,l,r) for(int i=l,i##_r=r;i<=i##_r;i++) 
    
    const int maxn = 2e5+10;
    const int inf = 1e9;
    const lf eps = 1e-8;
    const int mod = 1e9+7;
    
    int n,T;
    
    const int tmp[5][5] =
        {{1,1,0,0,0},
         {1,0,0,0,0},
         {2,0,1,1,0},
         {0,0,1,0,0},
         {mod-2,0,0,0,1}};
    
    int add(int x,int y) {return x+y>=mod?x+y-mod:x+y;}
    int del(int x,int y) {return x-y<0?x-y+mod:x-y;}
    int mul(int x,int y) {return 1ll*x*y-1ll*x*y/mod*mod;}
    
    struct Matrix {
        int a[6][6];
        Matrix () {memset(a,0,sizeof a);}
        Matrix operator * (const Matrix &r) const {
            Matrix res;
            for(int i=0;i<5;i++)
                for(int j=0;j<5;j++)
                    for(int k=0;k<5;k++)
                        res.a[i][j]=add(res.a[i][j],mul(a[i][k],r.a[k][j]));
            return res;
        }
        void print() {
            FOR(i,0,4){FOR(j,0,4)printf("%d ",a[i][j]);puts("");}puts("");
        }
    };
    
    Matrix qpow(Matrix a,int x) {
        Matrix res;for(int i=0;i<5;i++) res.a[i][i]=1;
        for(;x;x>>=1,a=a*a) if(x&1) res=res*a;
        return res;
    }
    
    void solve() {
        read(n);if(n<=2) return puts("0"),void();
        Matrix ans,res;
        FOR(i,0,4) FOR(j,0,4) res.a[i][j]=tmp[i][j];
        ans.a[0][2]=2,ans.a[0][3]=1,ans.a[0][4]=1;
        write((ans*qpow(res,n-2)).a[0][0]);
    }
    
    int main() {
        read(T);while(T--) solve();
        return 0;
    }
    
  • 相关阅读:
    虚拟机的类加载机制
    数组
    Intellij快捷键
    Wireshark过滤器语法设置
    Git命令(转)
    Git命令
    字节码指令简介(转)
    Java异常了解
    Class类文件的结构
    垃圾收集器与内存分配策略(六)之内存分配与回收策略
  • 原文地址:https://www.cnblogs.com/hbyer/p/10845206.html
Copyright © 2020-2023  润新知