列表

详情


NC20320. [SDOI2008]递归数列

描述

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

输入描述

由四行组成。
第一行是一个自然数k。
第二行包含k个自然数b1, b2,...,bk
第三行包含k个自然数c1, c2,...,ck
第四行包含三个自然数m, n, p。

输出描述

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

示例1

输入:

2
1 1
1 1
2 10 1000003

输出:

142

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(g++ 7.5.0) 解法, 执行用时: 12ms, 内存消耗: 456K, 提交时间: 2023-05-30 14:40:26

#include<iostream>
#include<algorithm>
#include<numeric>//accumulate(be,en,0)
#include<cstring>//find("string"),rfind("string"),s.find(string,begin)!=s.npos
#include<string>//to_string(value)
#include<cstdio>
#include<cmath>
#include<vector>//res.erase(unique(res.begin(), res.end()), res.end())
#include<queue>//priority_queue(big)  /priority_queue<int, vector<int>, greater<int>> q(small)
#include<stack>
#include<map>//unordered_map
#include<set>//iterator,insert(),erase(),lower(>=)/upper_bound(>)(value)/find()return end()
#define int long long
#define PII pair<int,int>
#define f first
#define s second
using namespace std;
const int inf=0x3f3f3f3f,K=17;
int b[K],c[K],k,d[K];
int m,n,mod;
void mul(int f[K],int a[K][K])
{
	int c[K];
	memset(c,0,sizeof c);
	for(int i=0;i<k+1;i++){
		for(int j=0;j<k+1;j++){
			c[i]=(c[i]+f[j]*a[i][j]%mod)%mod;
		}
	}
	memcpy(f,c,sizeof c);
}
void mulself(int a[K][K])
{
	int c[K][K];
	memset(c,0,sizeof c);
	for(int i=0;i<k+1;i++){
		for(int j=0;j<k+1;j++){
			for(int w=0;w<k+1;w++){
				c[i][j]=(c[i][j]+a[i][w]*a[w][j]%mod)%mod;
			}
		}
	}
	memcpy(a,c,sizeof c);
}
signed main()
{
	ios_base::sync_with_stdio(0); cin.tie(0),cout.tie(0);
	cin>>k;
	for(int i=1;i<=k;i++) cin>>b[i];
	for(int i=1;i<=k;i++) cin>>c[i];
	cin>>m>>n>>mod;
	for(int i=1;i<=k;i++) d[i]=(d[i-1]+b[i])%mod;
	int a[K][K];
	memset(a,0,sizeof a);
	a[0][0]=1;
	for(int i=1;i<=k;i++){
		a[0][i]=c[i];
		a[1][i]=c[i];
	}
	for(int i=2;i<=k;i++){
		a[i][i-1]=1;
	}
//	for(int i=0;i<=k;i++){
//		for(int j=0;j<=k;j++){
//			cout<<a[i][j]<<' ';
//		}
//		cout<<'\n';
//	}
    int f[K];
    f[0]=d[k];
    for(int i=1;i<=k;i++){
    	f[i]=b[k-i+1];
	}
	int x1=0;
	if(m-1<=k){
		x1=d[m-1];
	}else{
		int q=m-1-k;
		while(q){
			if(q&1) mul(f,a);
			q>>=1;
			mulself(a);
		}
		x1=f[0];
	}
    memset(a,0,sizeof a);
	a[0][0]=1;
	for(int i=1;i<=k;i++){
		a[0][i]=c[i];
		a[1][i]=c[i];
	}
	for(int i=2;i<=k;i++){
		a[i][i-1]=1;
	}
    f[0]=d[k];
    for(int i=1;i<=k;i++){
    	f[i]=b[k-i+1];
	}
// 	cout<<"x1:"<<x1<<'\n';
//    for(int i=0;i<=k;i++){
// 		for(int j=0;j<=k;j++){
// 			cout<<a[i][j]<<' ';
// 		}
// 		cout<<'\n';
// 	}
//     for(int i=0;i<=k;i++) cout<<f[i]<<' ';
	int x2=0;
	if(n<=k){
		x2=d[n];
	}else{
		int q=n-k;
		while(q){
			if(q&1) mul(f,a);
			q>>=1;
			mulself(a);
		}
		x2=f[0];
	}
	cout<<(x2-x1+mod)%mod;
}

C++14(g++5.4) 解法, 执行用时: 15ms, 内存消耗: 504K, 提交时间: 2019-11-11 20:48:47

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using std::min; using std::max;
using std::swap; using std::sort;
typedef long long ll;

template<typename T>
void read(T &x) {
    int flag = 1; x = 0; char ch = getchar();
    while(ch < '0' || ch > '9') { if(ch == '-') flag = -flag; ch = getchar(); }
    while(ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar();
	x *= flag;
}
#if __cplusplus >= 201103l
template<typename T, typename... V>
void read(T &x, V&... v) { read(x), read(v...); }
#endif

const int _ = 19;
int k, b[_], c[_], sl, sr, P; ll m, n;
inline void pls(int &a, int b) { a += b; if(a >= P) a -= P; }
struct matrix {
	int a[_][_];
	void clear() { memset(a, 0, sizeof a); }
	int *operator [] (int x) { return a[x]; }
    matrix operator * (matrix b) {
		matrix c; c.clear();
		for(int i = 1; i <= ::k + 1; ++i)
			for(int j = 1; j <= ::k + 1; ++j)
				for(int k = 1; k <= ::k + 1; ++k)
					pls(c[i][k], 1ll * a[i][j] * b[j][k] % P);
		return c;
	}
} S, T;

void pow(ll b) {
	for(; b; b >>= 1, T = T * T)
		if(b & 1) S = S * T;
}
void init() {
	S.clear(), T.clear();
	for(int i = 1; i < k; ++i) T[i + 1][i] = 1;
	T[k + 1][k + 1] = 1;
	for(int i = 1; i <= k; ++i) {
		T[i][k] = T[i][k + 1] = c[k - i + 1];
		pls(S[1][k + 1], b[i]), S[1][i] = b[i];
	}
}

int main () {
	read(k);
	for(int i = 1; i <= k; ++i) read(b[i]);
	for(int i = 1; i <= k; ++i) read(c[i]);
	read(m, n, P);
	if(m - 1 <= k)
		for(int i = 1; i <= m - 1; ++i) pls(sl, b[i]);
	else init(), pow(m - 1 - k), sl = S[1][k + 1];
	if(n <= k)
		for(int i = 1; i <= n; ++i) pls(sr, b[i]);
	else init(), pow(n - k), sr = S[1][k + 1];
	printf("%d\n", (sr + P - sl) % P);
	return 0;
}

C++11(clang++ 3.9) 解法, 执行用时: 14ms, 内存消耗: 376K, 提交时间: 2019-12-19 16:05:25

#include<bits/stdc++.h>
#define rgt register
#define rint rgt int
#define LL long long
#define rll rgt LL
#define inf 0x7f7f7f7f
using namespace std;
template<class K>inline bool cmax(K&a,const K&b){return (a<b)?a=b,1:0;}
template<class K>inline bool cmin(K&a,const K&b){return (a>b)?a=b,1:0;}
int K,p;LL l,r,sum,ans;
struct node{
	int m[17][17];
	inline node operator* (const node x) const{
		rgt node c;rll res;
		rint i,j,k;
		for(i=0;i<=K;++i) {
			for(j=0;j<=K;++j) {
				res=0;
				for(k=0;k<=K;k++)
					res+=(LL)m[i][k]*x.m[k][j]%p;
				c.m[i][j]=res%p;
			}
		}return c;
	}
}E,A,res,a;
inline int Pow(rll b) {
	res=E,a=A;
	for(;b;b>>=1,a=a*a)
		if(b&1) res=res*a;
	return res.m[0][0];
}
int main()
{
	rint i;scanf("%d",&K);
	for(i=1;i<=K;i++) scanf("%d",&E.m[0][K-i+1]),sum+=E.m[0][K-i+1];
	for(i=1;i<=K;i++) scanf("%d",&A.m[i][1]);A.m[0][0]=A.m[1][0]=1;
	for(i=2;i<=K;i++) A.m[i-1][i]=1;
	scanf("%lld%lld%d",&l,&r,&p),--l;E.m[0][0]=(sum-E.m[0][1])%p;
	if(l<K) for(i=1;i<=l;i++) ans-=E.m[0][K-i+1];
	else ans=-Pow(l-K+1);
	if(r<K) for(i=1;i<=r;i++) ans+=E.m[0][K-i+1];
	else ans+=Pow(r-K+1);
	printf("%d",(ans%p+p)%p);
	return 0;
}

上一题