zoukankan      html  css  js  c++  java
  • 【SDOI 2008】 递归数列

    【题目链接】

              点击打开链接

    【算法】

              矩阵乘法优化递推

              由于本博客不支持数学公式,所以不能将矩阵画出来,请谅解!

    【代码】

             

    #include<bits/stdc++.h>
    using namespace std;
    #define MAXK 18
    
    struct Matrix 
    {
            long long mat[MAXK][MAXK];
    };
    
    int i,k;
    long long n,m,p,sum;
    long long b[MAXK],c[MAXK];
    
    template <typename T> inline void read(T &x)
    {
        long long f = 1; x = 0;
        char c = getchar();
        for (; !isdigit(c); c = getchar()) { if (c == '-') f = -f; }
        for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0';
        x *= f;
    }
    template <typename T> inline void write(T x)
    {
        if (x < 0)
        {
            putchar('-');
            x = -x;
        }
        if (x > 9) write(x/10);
        putchar(x%10+'0');
    }
    template <typename T> inline void writeln(T x)
    {
        write(x);
        puts("");
    }
    
    inline void multipy(Matrix &a,Matrix b)
    {
            int i,j,t;
            Matrix ans;
            memset(ans.mat,0,sizeof(ans.mat));
            for (i = 1; i <= k + 1; i++)
            {
                    for (j = 1; j <= k + 1; j++)
                    {
                            for (t = 1; t <= k + 1; t++)
                            {
                                    ans.mat[i][j] = (ans.mat[i][j] + a.mat[i][t] * b.mat[t][j]) % p;
                            }
                    }
            }
            a = ans;
    }
    inline long long solve(long long n)
    {
            Matrix a,res;
            int i,j;
            long long ans = 0;
            memset(a.mat,0,sizeof(a.mat));
            for (i = 2; i <= k + 1; i++) a.mat[1][i] = a.mat[2][i] = c[i-1];
            for (i = 3; i <= k + 1; i++) a.mat[i][i-1] = 1;
            a.mat[1][1] = 1;
            memset(res.mat,0,sizeof(res.mat));
            for (i = 1; i <= k + 1; i++) res.mat[i][i] = 1;
            while (n > 0)
            {
                    if (n & 1) multipy(res,a);
                    multipy(a,a);
                    n >>= 1;
            }
            ans = sum;
            for (i = 2; i <= k + 1; i++) ans = (ans + res.mat[1][i] * b[k-i+2]) % p;
            return ans;
    }
    inline long long query(long long n)
    {
            int i;
            long long ans = 0;
            if (n <= k)
            {
                    for (i = 1; i <= n; i++) ans = (ans + b[i]) % p;
                    return ans;
            } else return solve(n-k);
    }
    
    int main() {
            
            read(k);
            for (i = 1; i <= k; i++) read(b[i]);
            for (i = 1; i <= k; i++) read(c[i]);
            read(m); read(n); read(p);
            for (i = 1; i <= k; i++) sum = (sum + b[i]) % p;
            writeln((query(n) - query(m-1) + p) % p);
            
            return 0;
        
    }
  • 相关阅读:
    001-快速排序(C++实现)
    NDK: ant 错误 [javah] Exception in thread "main" java.lang.NullPointerException 多种解决办法
    jenkins数据迁移方案
    gitlab仓库迁移方案
    rancher中搭建elk,部分配置文件
    Spring事务传播行为详解
    Linux下安装配置启动RabbitMQ
    Nginx做代理路由时,不转发http的header问题
    @Validated @RequestBody @RequestParam配合使用校验参数
    jenkins环境搭建
  • 原文地址:https://www.cnblogs.com/evenbao/p/9196309.html
Copyright © 2011-2022 走看看