結果
| 問題 |
No.194 フィボナッチ数列の理解(1)
|
| コンテスト | |
| ユーザー |
koyumeishi
|
| 提出日時 | 2015-05-25 21:42:23 |
| 言語 | C++11(廃止可能性あり) (gcc 13.3.0) |
| 結果 |
AC
|
| 実行時間 | 16 ms / 5,000 ms |
| コード長 | 2,497 bytes |
| コンパイル時間 | 737 ms |
| コンパイル使用メモリ | 91,016 KB |
| 実行使用メモリ | 16,756 KB |
| 最終ジャッジ日時 | 2024-07-06 08:29:53 |
| 合計ジャッジ時間 | 1,773 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 37 |
ソースコード
#include <iostream>
#include <vector>
#include <cstdio>
#include <sstream>
#include <map>
#include <string>
#include <algorithm>
#include <queue>
#include <cmath>
#include <set>
#include <functional>
using namespace std;
#define MOD 1000000007
template<class T>
class kitamasa{
public:
int max_n;
vector<T> A;
vector<T> X;
kitamasa(vector<T>& a, vector<T>& x){
for(int i=0; i<a.size(); i++){ A.push_back(a[i]); }
//X.push_back(0);
for(int i=0; i<x.size(); i++){ X.push_back(x[i]); }
}
//ΣΣ Pi Qj X(i+j) -> Σ Ri Xi ( i = 0...d )
vector<T> func(const vector<T>& P, const vector<T>& Q){
int d = A.size();
vector<T> tmp(2*d-1, 0);
for(int i=0; i<d; ++i){
for(int j=0; j<d; ++j){
tmp[i+j] += (P[i]*Q[j]%MOD + MOD);
if(tmp[i+j] >= MOD) tmp[i+j] %= MOD;
}
}
for(int i=2*d-2; i>=d; --i){
for(int j=0; j<d; ++j){
tmp[i - d + j] += (tmp[i] * A[j] % MOD + MOD)%MOD;
if(tmp[i - d + j] >= MOD) tmp[i - d + j] %= MOD;
}
}
tmp.resize(d);
return tmp;
}
T calc(T k){
int d = A.size();
int lg = 0;
while((1LL<<lg) <= k) lg++;
// X[2^n] = Σ B[n][i] X[i] (i = 0...d)
vector<vector<T>> B(lg, vector<T>(d, 0));
B[0][1] = 1;
for(int i=0; i+1<lg; i++){
B[i+1] = func(B[i], B[i]);
}
vector<T> res = B[0];
int r = 0;
while(k){
if(k & 1){
res = func(res, B[r]);
}
k>>=1;
r++;
}
T ret = 0;
for(int i=0; i<d; i++){
ret += (res[i] * X[i] % MOD + MOD)%MOD;
ret %= MOD;
}
return ret;
}
};
void solve_normal(long long n, long long k){
cerr << " solver :: normal " << endl;
vector<long long> x(n+2, 0);
for(int i=0; i<n; i++){
cin >> x[i+2];
}
for(int i=1; i<x.size(); i++){
x[i] += x[i-1];
}
for(int i=x.size(); i<=k+1; i++){
x.push_back((2*x[i-1] - x[i-1-n] + MOD)%MOD);
}
cout << (x[k+1]-x[k]+MOD)%MOD << " " << x[k+1] << endl;
}
void solve_kitamasa(long long n, long long k){
cerr << " solver :: kitamasa " << endl;
vector<long long> a(n+2, 1);
a[0] = a[1] = 0;
vector<long long> x(n+2, 0);
for(int i=0; i<n; i++){
cin >> x[i+2];
}
kitamasa<long long> ktms_f(a,x);
cout << ktms_f.calc(k) << " ";
vector<long long> b(n+2, 0);
b[1] = -1; b[n+1] = 2;
vector<long long> y = x;
for(int i=1; i<y.size(); i++){
y[i] += y[i-1];
}
kitamasa<long long> ktms_s(b,y);
cout << ktms_s.calc(k) << endl;
}
int main(){
long long n,k;
cin >> n >> k;
function<void(long long,long long)> solver = (n<=30? solve_kitamasa : solve_normal);
solver(n,k);
return 0;
}
koyumeishi