zoukankan      html  css  js  c++  java
  • luogu2461递归数列

    题目描述

    一个由自然数组成的数列按下式定义:

    对于i <= k:ai = bi
    对于i > k: ai = c1ai-1 + c2ai-2 + … + ckai-k
    其中bj 和 cj (1<=j<=k)是给定的自然数。写一个程序,给定自然数m <= n, 计算am + am+1 + am+2 + … + an, 并输出它除以给定自然数p的余数的值。

    输入输出格式

    输入格式:
    输入文件spp.in由四行组成。
    第一行是一个自然数k。
    第二行包含k个自然数b1, b2,…,bk。
    第三行包含k个自然数c1, c2,…,ck。
    第四行包含三个自然数m, n, p。

    输出格式:
    输出文件spp.out仅包含一行:一个正整数,表示(am + am+1 + am+2 + … + an) mod p的值。

    输入输出样例

    输入样例#1:
    2
    1 1
    1 1
    2 10 1000003

    输出样例#1:
    142

    说明

    对于100%的测试数据:
    1<= k <=15
    1 <= m <= n <= 1018
    对于20%的测试数据:
    1<= k <=15
    1 <= m <= n <= 106
    对于30%的测试数据:
    k=1 1 <= m <= n <= 1018
    对于所有测试数据:
    0<= b1, b2,… bk, c1, c2,…, ck<=109
    1 <= p <= 108

    这里写图片描述

    这里写代码片
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #define LL long long 
    
    using namespace std;
    
    const int N=20;
    int k;
    LL n,mm,mod;
    LL b[N],c[N];
    LL tot=0;
    
    struct node{
        LL m[N][N];
        node operator *(const node &a) const{
            node ans;
            for (int i=1;i<=k;i++)
                for (int j=1;j<=k;j++)
                {
                    ans.m[i][j]=0;
                    for (int l=1;l<=k;l++)
                        ans.m[i][j]=(ans.m[i][j]+m[i][l]*a.m[l][j])%mod;
                }
            return ans;  ///
        }
        void clear()
        {
            memset(m,0,sizeof(m));
        }
        LL KSM(LL pp)
        {
            LL p;
            if (pp<=k)  //用不到矩乘 
            {
                LL an=0;
                for (int i=1;i<=pp;i++)  //直接暴力 
                    an=(an+b[i])%mod;
                return an%mod;
            }
            p=pp-k; //真心。。对样例调一调就好了 
            node ans=(*this),a=(*this);
            while (p)
            {
                if (p&1)
                   ans=ans*a;
                a=a*a;
                p>>=1;
            }
            LL r=0;
            for (int i=1;i<k;i++)
                r=(r+(ans.m[i][k]*b[k-i])%mod)%mod;  //计算前缀和 
            r=(r+(tot*ans.m[k][k])%mod)%mod;
            return r;  //sum
        }
    };
    
    int main()
    {
        scanf("%d",&k);
        for (int i=1;i<=k;i++) scanf("%lld",&b[i]); 
        for (int i=1;i<=k;i++) scanf("%lld",&c[i]);
        scanf("%lld%lld%lld",&mm,&n,&mod);
        for (int i=1;i<=k;i++) tot=(tot+b[i]%mod)%mod;  //tot前缀和 
        node m,t;
        m.clear(); t.clear();
        for (int i=1;i<=k;i++)   //矩阵的初始值 
        { //在矩阵中我们要维护一个前缀和 
            m.m[i][1]=c[i];
            m.m[i][k+1]=c[i];
            t.m[i][1]=c[i];
            t.m[i][k+1]=c[i];
        }
        for (int i=1;i<k;i++) m.m[i][i+1]=1,t.m[i][i+1]=1;
        m.m[k+1][k+1]=1;
        t.m[k+1][k+1]=1;
        k++;
        LL an=0;
        an+=m.KSM(n);
        an-=t.KSM(mm-1);
        printf("%lld",(an+mod)%mod);  //题目有漏洞,在最后的%处理时要先+mod再% 
        return 0;
    }
  • 相关阅读:
    非常有助于理解二极管PN结原理的资料
    5个CSS3技术实现设计增强
    如何读懂Web服务的系统架构图
    网页布局WEB标准的HTML结构化
    网站内容排版可用性分析
    用CSS做导航菜单的4个理由
    提高网站设计可用性(有效性)的10条原则
    dl,dt,dd标签 VS 传统table实现数据列表
    一些CSS3新技术
    21个CSS技巧
  • 原文地址:https://www.cnblogs.com/wutongtong3117/p/7673599.html
Copyright © 2011-2022 走看看