zoukankan      html  css  js  c++  java
  • [luogu2461 SDOI2008] 递归数列 (矩阵乘法)

    传送门

    Description

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

    对于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的余数的值。

    Input

    输入文件spp.in由四行组成。

    第一行是一个自然数k。

    第二行包含k个自然数b1, b2,...,bk。

    第三行包含k个自然数c1, c2,...,ck。

    第四行包含三个自然数m, n, p。

    Output

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

    Sample Input

    2
    1 1
    1 1
    2 10 1000003

    Sample Output

    142

    HINT

    对于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

    Solution

    构造矩阵然后直接乘
    注意乘的顺序还有最后一定要再MOD一次以防万一qwq

    Code

    //By Menteur_Hxy
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<iostream>
    #include<algorithm>
    #define F(i,a,b) for(register int i=(a);i<=(b);i++)
    using namespace std;
    typedef long long LL;
    
    LL read() {
    	LL x=0,f=1; char c=getchar();
    	while(!isdigit(c)) {if(c=='-')f=-f;c=getchar();}
    	while(isdigit(c)) x=(x<<1)+(x<<3)+c-48,c=getchar();
    	return x*f;
    }
    
    const int K=20;
    int k;
    int c[K],b[K];
    LL n,m,MOD,ans1,ans2,s[K];
    struct Matrix{
    	LL da[K][K];
    	Matrix() {clear();};
    	void clear() {memset(da,0,sizeof(da));}
    	Matrix operator * (const Matrix oth) {
    		Matrix res; 
    		F(i,0,k) F(j,0,k) F(l,0,k) 
    			res.da[i][j]=(res.da[i][j]+oth.da[i][l]*da[l][j]%MOD)%MOD;
    		return res;
    	}
    	void print() {
    		F(i,0,k) {
    			F(j,0,k) cout<<da[i][j]<<" ";
    			cout<<endl;
    		}cout<<endl;
    	}
    }ans,st;
    
    Matrix Qpow(Matrix a,LL d) {
    	Matrix ret;
    	ret.da[0][0]=s[k];
    	F(i,1,k) ret.da[i][0]=b[k-i+1];
    	while(d) {
    		if(d&1) ret=ret*a;
    		a=a*a; d>>=1;
    //		a.print();
    	}
    	return ret;
    }
    
    int main() {
    	k=read();
    	F(i,1,k) b[i]=read(),s[i]=s[i-1]+b[i];
    	F(i,1,k) c[i]=read();
    	m=read(),n=read(),MOD=read();
    	st.da[0][0]=1;
    	F(i,1,k) st.da[0][i]=st.da[1][i]=c[i];
    	F(i,2,k) st.da[i][i-1]=1;
    //	st.print();
    	if(n<=k) {
    		printf("%lld",s[n]-s[m-1]);
    		return 0;
    	} else {
    		ans=Qpow(st,n-k);
    //		ans.print();
    		ans1=ans.da[0][0];
    	}
    	if(m<=k) ans2=s[m-1];
    	else {
    		ans=Qpow(st,m-k-1);
    //		ans.print();
    		ans2=ans.da[0][0];
    	}
    	printf("%lld",(ans1-ans2+MOD)%MOD);
    	return 0;
    }
    
    版权声明:本文为博主原创文章,未经博主允许不得转载。 博主:https://www.cnblogs.com/Menteur-Hxy/
  • 相关阅读:
    pip install pli 提示:Could not find a version that satisfies the requirement PIL
    关于selenium部分元素定位不到的解决办法
    ERROR 1054 (42S22): Unknown column ‘password‘ in ‘field list‘
    通过Tomcat jpress连接不到数据库
    Navicat MySQL 连接出现 Authentication plugin ‘caching_sha2_password‘ cannot be loaded
    Selenium中核心属性以及方法
    selenium中定位frame中的元素
    selenium中截屏以及按照时间格式保存到相应文件夹
    Selenium中核心属性以及方法
    selenium中关于js脚本的一些操作
  • 原文地址:https://www.cnblogs.com/Menteur-Hxy/p/9379780.html
Copyright © 2011-2022 走看看