hdu3483 A Very Simple Problem
2014-11-12 17:19 达利园大面包 阅读(193) 评论(0) 收藏 举报理论上高斯消元可以做,实际上我*&%^&%$^&.
理论上可以构造出矩阵,可是我不会,后来看了题解,真是手贱.
有了初始向量很好递推的,由于手贱,没有初始化,WA几发.
-----------------------------------------------------------
#include <cstdio>
#include <cstring>
using namespace std;
long long com[100][100],a[100][100],tmp[100][100];
long long n,x,m;
void quick_pow(long long k){
if (k==0){
memset(a,0,sizeof(a));
for (int i=0;i<=x+1;i++){
a[i][i] = 1;
}
return ;
}
quick_pow(k/2);
for (int i=0;i<=x+1;i++){
for (int j=0;j<=x+1;j++){
tmp[i][j] = 0;
for (int k=0;k<=x+1;k++){
tmp[i][j] = (tmp[i][j] + a[i][k] * a[k][j] % m) % m;
}
}
}
if (k&1){
for (int i=0;i<=x+1;i++){
for (int j=0;j<=x+1;j++){
a[i][j] = 0;
for (int k=0;k<=x+1;k++){
a[i][j] = (a[i][j] + tmp[i][k] * com[k][j] % m) % m;
}
}
}
}else{
for (int i=0;i<=x+1;i++){
for (int j=0;j<=x+1;j++){
a[i][j] = tmp[i][j];
}
}
}
}
int main(){
while (scanf("%I64d%I64d%I64d",&n,&x,&m)!=EOF){
if (n<0||x<0||m<0) break;
com[0][0] = x % m;
com[1][0] = x % m;
com[1][1] = x % m;
for (int i=2;i<=x;i++){
com[i][0] = x % m;
for (int j=1;j<=i;j++){
com[i][j] = (com[i-1][j-1] + com[i-1][j]) % m;
}
}
for (int i=0;i<x;i++) com[x+1][i] = 0;
com[x+1][x] = com[x+1][x+1] = 1;
quick_pow(n);
long long ans = 0;
for (int i=0;i<=x;i++) ans = (ans + a[x+1][i]) % m;
printf("%I64d\n",ans * x % m);
}
return 0;
}
浙公网安备 33010602011771号