CSES - TCR Contest - Results
Submission details
Task:Fibonacci String
Sender:Tuukka Korhonen
Submission time:2017-11-21 16:37:36 +0200
Language:C++
Status:READY
Result:ACCEPTED
Test results
testverdicttime
#1ACCEPTED0.97 sdetails
#2ACCEPTED0.19 sdetails
#3ACCEPTED0.24 sdetails
#4ACCEPTED0.99 sdetails
#5ACCEPTED0.29 sdetails
#6ACCEPTED0.03 sdetails
#7ACCEPTED0.06 sdetails
#8ACCEPTED0.06 sdetails
#9ACCEPTED0.11 sdetails

Code

#include <bits/stdc++.h>
#define F first
#define S second
using namespace std;
typedef long long ll;

ll powmod(ll a, ll p, ll modd) {
	if (p==0) return 1;
	if (p%2==0) {
		a=powmod(a, p/2, modd);
		return (a*a)%modd;
	}
	return (a*powmod(a, p-1, modd))%modd;
}
ll invp(ll a, ll p) {
	return powmod(a, p - 2, p);
}
vector<ll> solve(vector<ll> S, ll mod) {
	vector<ll> C = {1};
	vector<ll> B = {1};
	ll L = 0;ll m = 1;ll b = 1;ll N = S.size();
	for (ll i = 0; i < N; i++) {
		ll d = S[i];
		for (ll j = 1; j <= L; j++) {
			d += C[j]*S[i - j];d %= mod;
		}
		if (d == 0) {
			m++;
		} else if (2*L <= i) {
			vector<ll> T = C;
			ll a = (invp(b, mod)*d)%mod;
			for (int j=0;j<i+1-2*L;j++) {
				C.push_back(0);
			}
			L=i+1-L;
			for (ll j = m; j <= L; j++) {
				C[j] -= a*B[j - m];C[j] %= mod;
			}
			B = T;b = d;m = 1;
		} else {
			ll a = (invp(b, mod)*d)%mod;
			for (ll j = m; j < m+(int)B.size(); j++) {
				C[j] -= a*B[j - m];C[j] %= mod;
			}
			m++;
		}
	}
	for (ll i = 0; i <= L; i++) {
		C[i] += mod;C[i] %= mod;
	}
	return C;
}
struct LinearRecurrence {
	vector<vector<ll> > mat;
	vector<ll> seq;
	ll mod;
	vector<vector<ll> > mul(vector<vector<ll> > a, vector<vector<ll> > b) {
		int n=a.size();
		vector<vector<ll> > ret(n);
		for (int i=0;i<n;i++){
			ret[i].resize(n);
			for (int j=0;j<n;j++){
				ret[i][j]=0;
				for (int k=0;k<n;k++){
					ret[i][j]+=a[i][k]*b[k][j];
					ret[i][j]%=mod;
				}
			}
		}
		return ret;
	}
	vector<vector<ll> > pot(vector<vector<ll> > m, ll p) {
		if (p==1) return m;
		if (p%2==0) {
			m=pot(m, p/2);
			return mul(m, m);
		}
		else {
			return mul(m, pot(m, p-1));
		}
	}
	ll get(ll index) {
		if (index<(ll)mat.size()) {
			return seq[index];
		}
		vector<vector<ll> > a=pot(mat, index-(ll)mat.size()+1);
		ll v=0;
		for (int i=0;i<(int)mat.size();i++) {
			v+=a[0][i]*seq[(int)mat.size()-i-1];
			v%=mod;
		}
		return v;
	}
	LinearRecurrence(vector<ll> S, ll mod_) {
		seq=S;
		mod=mod_;
		vector<ll> C=solve(S, mod);
		int n=C.size()-1;
		mat.resize(n);
		for (int i=0;i<n;i++) {
			mat[i].resize(n);
		}
		for (int i=0;i<n;i++) {
			mat[0][i]=(mod-C[i+1])%mod;
		}
		for (int i=1;i<n;i++) {
			mat[i][i-1]=1;
		}
	}
};

const ll mod=1e9+7;

const int N=500;

ll dp[N+20][N+20][2];

struct FibonacciStringSum{
	int get(int n, int a, int b){
		dp[0][0][0]=1;
		for (int i=0;i<N;i++){
			for (int j=0;j<=i;j++){
				for (int e=0;e<2;e++){
					ll t=dp[i][j][e];
					dp[i+1][j+1][0]+=t;
					dp[i+1][j+1][0]%=mod;
					
					if (e==0){
						dp[i+1][j][1]+=t;
						dp[i+1][j][1]%=mod;
					}
				}
			}
		}
		vector<ll> ans;
		for (int i=1;i<=N;i++){
			ll t=0;
			for (int j=0;j<=N;j++){
				t+=(dp[i][j][0]+dp[i][j][1])*((powmod(j, a, mod)*powmod(i-j, b, mod))%mod);
				t%=mod;
			}
			ans.push_back(t);
		}
		LinearRecurrence lr(ans, mod);
		return lr.get(n-1);
	}
};

int main(){
	FibonacciStringSum fss;
	int n, a, b;
	cin>>n>>a>>b;
	assert(n>=1&&n<=1000000000);
	assert(0<=a&&a<=25);
	assert(0<=b&&b<=25);
	cout<<fss.get(n, a, b)<<endl;
}

Test details

Test 1

Verdict: ACCEPTED

input
1000000000 25 25

correct output
572727199

user output
572727199

Test 2

Verdict: ACCEPTED

input
1000000000 25 0

correct output
972755876

user output
972755876

Test 3

Verdict: ACCEPTED

input
1000000000 0 25

correct output
660783451

user output
660783451

Test 4

Verdict: ACCEPTED

input
123456789 25 25

correct output
539661624

user output
539661624

Test 5

Verdict: ACCEPTED

input
123456789 12 18

correct output
405307844

user output
405307844

Test 6

Verdict: ACCEPTED

input
1 0 0 

correct output
2

user output
2

Test 7

Verdict: ACCEPTED

input
1 0 1

correct output
1

user output
1

Test 8

Verdict: ACCEPTED

input
1 1 0

correct output
1

user output
1

Test 9

Verdict: ACCEPTED

input
1 25 25

correct output
0

user output
0