Pagini recente » Profil CroitoruAlin | Cod sursa (job #396960) | Cod sursa (job #2949864) | Cod sursa (job #2281092) | Cod sursa (job #872145)
Cod sursa(job #872145)
#include<stdio.h>
#include<cstring>
#include<algorithm>
#include<deque>
#define maxm 1005
#define maxk 23
#define mod 9901
using namespace std;
FILE*f=fopen("pod.in","r");
FILE*g=fopen("pod.out","w");
int n,m,k;
int p[maxm],M[maxk][maxk],aux[maxk][maxk],S[maxk][maxk],P[maxk][maxk],C[maxk][maxk];
int last[maxk],now[maxk];
deque<int>D;
inline void copiaza ( int A[maxk][maxk] , int B[maxk][maxk] ){
for ( int i = 1 ; i <= k ; ++i ){
for ( int j = 1 ; j <= k ; ++j ){
A[i][j] = B[i][j];
}
}
}
inline void mult ( int A[maxk][maxk] , int B[maxk][maxk] ){
memset(C,0,sizeof(C));
for ( int i = 1 ; i <= k ; ++i ){
for ( int j = 1 ; j <= k ; ++j ){
for ( int aux = 1 ; aux <= k ; ++aux ){
C[i][j] = (C[i][j] + A[i][aux]*B[aux][j])%mod;
}
}
}
copiaza(A,C);
}
inline void lgpow ( int A[maxk][maxk] , int b ){
memset(S,0,sizeof(S));
for ( int i = 1 ; i <= k ; ++i ) S[i][i] = 1;
copiaza(P,A);
while ( b ){
if ( b & 1 ){
mult(S,P);
}
mult(P,P);
b >>= 1;
}
copiaza(A,S);
}
int main () {
fscanf(f,"%d %d %d",&n,&m,&k);
for ( int i = 1 ; i <= m ; ++i ){
fscanf(f,"%d",&p[i]);
}
sort(p+1,p+m+1); p[++m] = n;
M[1][1] = M[1][k] = 1;
for ( int i = 2 ; i <= k ; ++i ) M[i][i-1] = 1;
int from = 0,sol = -1; last[0] = 1;
for ( int i = 1 ; i <= m ; ++i ){
copiaza(aux,M);
lgpow(aux,p[i]-from);
for ( int j = 0 ; j < k ; ++j ){
now[j] = 0;
for ( int x = 1 ; x <= k ; ++x ){
now[j] = (now[j] + aux[j+1][x]*last[x-1])%mod;
}
}
if ( i == m ){
sol = now[0];
break ;
}
while(!D.empty()) D.pop_back();
for ( int j = 1 ; j < k ; ++j ){
D.push_front(now[j]);
}
D.push_back(0);
int ultima = p[i],acum = p[i],next = i+1;
do{
++acum;
if ( p[next] == acum ){
ultima = p[next];
++next; D.push_back(0); ++i;
if ( acum == n ){
sol = D[0]+D[k-1]; if ( sol >= mod ) sol -= mod;
break ;
}
}
else{
D.push_back(D[0]+D[k-1]); if ( D[k] >= mod ) D[k] -= mod;
if ( acum == n ){
sol = D[k]; break ;
}
}
D.pop_front();
}while ( acum-ultima < k && sol == -1 );
if ( sol != -1 ) break ;
for ( int i = 0 ; i < k ; ++i ){
last[k-i-1] = D[i];
}
from = acum;
}
fprintf(g,"%d\n",sol);
fclose(f);
fclose(g);
return 0;
}