Pagini recente » Istoria paginii runda/cel_mai_mare_olimpicar_2019_oni2008_zi2 | Algoritmiada 2009 - Clasament Runda 2, Studenti | Cod sursa (job #513364) | Cod sursa (job #2014429) | Cod sursa (job #2243335)
#include <stdio.h>
#include <algorithm>
using namespace std;
int n, m, k, poz[1005], mod=9901;
int dp[40], F[40][2], T[40][40];
void inm(int a[40][40], int b[40][40]){
int rez[40][40];
int i,j,l;
for(i=1; i<=k; i++)
for(j=1; j<=k; j++)
{
rez[i][j]=0;
for(l=1; l<=k; l++)
{
rez[i][j]+=a[i][l]*b[l][j];
rez[i][j]%=mod;
}
}
for(i=1; i<=k; i++)
for(j=1; j<=k; j++)
a[i][j]=rez[i][j];
}
void ridica(int T[40][40], int p){
int rez[40][40];
for(int i=1; i<=k; i++)
for(int j=1; j<=k; j++)
if(i==j) rez[i][j]=1;
else rez[i][j]=0;
while(p>0){
if(p&1) inm(rez, T);
inm(T,T);
p=p>>1;
}
for(int i=1; i<=k; i++)
for(int j=1; j<=k; j++)
T[i][j]=rez[i][j];
}
void inmulteste(int T[40][40], int F[40][2]){
int rez[40][2];
int i, j;
for(i=1; i<=k; i++){
rez[i][1]=0;
for(j=1; j<=k; j++){
rez[i][1]+=T[i][j]*F[j][1];
rez[i][1]%=mod;
}
}
for(i=1; i<=k; i++)
F[i][1]=rez[i][1];
}
int main(){
freopen("pod.in", "r", stdin);
freopen("pod.out", "w", stdout);
int i, j;
int l, putere;
scanf("%d%d%d",&n, &m, &k);
for(i=1; i<=m; i++)
scanf("%d", &poz[i]);
m++; poz[m]=n+1;
m++; poz[m]=0;
sort(poz+1, poz+m+1);
//dp-ultimele k valori, dp[k]-> val de pe pozitia 0/ poz interzise (dp[k]= 1 intial/0 pe urma)
for(i=1; i<k; i++) dp[i]=0; dp[k]=1;
for(l=2; l<=m; l++){
putere=poz[l]-poz[l-1]-1;
for(i=1; i<=k; i++)
F[i][1]=dp[i];
for(i=1; i<=k; i++)
for(j=1; j<=k; j++)
if(i+1==j) T[i][j]=1;
else T[i][j]=0;
T[k][1]=1; T[k][k]=1;
for(i=2; i<k; i++)
T[k][i]=0;
ridica(T, putere);
inmulteste(T, F) ;
dp[k]=0;
for(i=1; i<k; i++)
dp[i]=F[i+1][1];
}
printf("%d", dp[k-1]);
return 0;
}