HDU1757
递推式给了,入门裸题。
Code:
#include <bits/stdc++.h>
#pragma comment(linker, “/STACK:1024000000,1024000000”)
#define INF 0x3f3f3f3f
#define LL long long
using namespace std;
LL k ;
int m ;
int b[15];
struct Matrix{
LL a[12][12];
};
Matrix Mul( Matrix x , Matrix y ){
Matrix res ;
memset( res.a , 0 , sizeof(res.a) );
for( int i = 0 ; i < 10 ; i++ ){
for( int j = 0 ; j < 10 ; j++ ){
for( int k = 0 ; k < 10; k++ ){
res.a[i][j] = ( res.a[i][j] + x.a[i][k] * y.a[k][j] % m ) % m;
}
}
}
return res ;
}
Matrix quick( Matrix x , int b ){
Matrix ans ;
memset( ans.a , 0 , sizeof(ans.a) );
for( int i = 0 ; i < 10 ; i++ ) ans.a[i][i] = 1 ;
while( b ){
if( b & 1 ){
ans = Mul( ans , x );
}
b >>= 1 ;
x = Mul( x , x ) ;
}
return ans ;
}
int main(){
while( ~scanf("%lld%d",&k,&m) ){
if( k < 10 ){
printf("%d\n",k%m);
continue ;
}
Matrix mat ;
memset( mat.a , 0 , sizeof(mat.a) );
for( int i = 0 ; i < 10 ; i++ ){
scanf("%d",&mat.a[0][i]);
}
for( int i = 1 ; i < 10 ; i++ ){
mat.a[i][i-1] = 1;
}
Matrix s = quick( mat , k - 9 );
Matrix ans ;
memset( ans.a , 0 , sizeof(ans.a) );
for( int i = 0 ; i < 10 ; i++ ) ans.a[i][0] = 9 - i ;
LL res = 0;
for( int i = 0 ; i < 10 ; i++ ){
res = ( res + s.a[0][i] * ans.a[i][0] ) % m;
}
printf("%d\n",res);
}
return 0 ;
}
HDU1575
更裸。。
Code:
#include <bits/stdc++.h>
#pragma comment(linker, “/STACK:1024000000,1024000000”)
#define INF 0x3f3f3f3f
#define LL long long
using namespace std;
const int MOD = 9973 ;
struct Matrix{
LL a[12][12];
};
int n , k ;
Matrix Mul( Matrix x , Matrix y ){
Matrix ans ;
memset( ans.a , 0 , sizeof(ans.a) );
for( int i = 0 ; i < n ; i++ ){
for( int j = 0 ; j < n ; j++ ){
for( int k = 0 ; k < n ; k++ ){
ans.a[i][j] = ( ans.a[i][j] + x.a[i][k] * y.a[k][j] % MOD ) % MOD;
}
}
}
return ans ;
}
Matrix quick( Matrix a , int b ){
Matrix ans ;
memset( ans.a , 0 ,sizeof(ans.a) );
for( int i = 0 ; i < n ; i++ ) ans.a[i][i] = 1 ;
while( b ){
if( b & 1 ) ans = Mul( ans , a );
b >>= 1 ;
a = Mul( a , a );
}
return ans ;
}
int main(){
int T;
scanf("%d",&T);
while( T-- ){
scanf("%d%d",&n,&k);
Matrix Mat;
memset( Mat.a , 0 , sizeof(Mat.a) );
for( int i = 0 ; i < n ; i++ ){
for( int j = 0 ; j < n ; j++ ){
scanf("%d",&Mat.a[i][j]);
}
}
Matrix res = quick( Mat , k ) ;
int ans = 0 ;
for( int i = 0 ; i < n ; i++ ){
ans = ( ans + res.a[i][i] ) % MOD ;
}
printf("%d\n",ans);
}
return 0 ;
}
HDU2604
题意:对于只由数字1和0构成的字符串,给出长度为n的,不含子串101且不含子串111的字符串的个数对m取模的值。
推公式:f[n] 为满足条件的长度n的串的个数
如果最后一个为0,那么结果就是f(n-1) 后面加0,肯定不会出现101,111
如果最后一个为1,还要考虑前面2位必须为00 (f[n-3]), 01(前面必须为0)所以就是f[n-4]
得到:f[n] = f [n-1] + f[n-3] + f[n-4]
Code:
#include <bits/stdc++.h>
#pragma comment(linker, “/STACK:1024000000,1024000000”)
#define INF 0x3f3f3f3f
#define LL long long
using namespace std;
int n , m ;
struct Matrix{
int a[4][4];
};
Matrix Mul( Matrix x , Matrix y ){
Matrix ans ;
memset( ans.a , 0 , sizeof(ans) );
for( int i = 0 ; i < 4 ; i++ ){
for( int j = 0 ; j < 4 ; j++ ){
for( int k = 0 ; k < 4 ; k++ ){
ans.a[i][j] = ( ans.a[i][j] + x.a[i][k] * y.a[k][j] % m ) % m ;
}
}
}
return ans ;
}
Matrix quick( Matrix x , int b ){
Matrix ans;
memset( ans.a , 0 , sizeof(ans) );
for( int i = 0 ; i < 4 ; i++ ) ans.a[i][i] = 1 ;
while( b ){
if( b & 1 ) ans = Mul( ans , x );
x = Mul(x,x);
b >>= 1 ;
}
return ans ;
}
int main(){
while( ~scanf("%d%d",&n,&m) ){
if( n == 0 ) printf("0\n");
else if( n == 1 ) printf("%d\n",2%m);
else if( n == 2 ) printf("%d\n",4%m);
else if( n == 3 ) printf("%d\n",6%m);
else if( n == 4 ) printf("%d\n",9%m);
else{
Matrix ans ;
memset( ans.a , 0 , sizeof(ans.a) );
ans.a[0][0] = 1 ; ans.a[0][1] = 0 ; ans.a[0][2] = 1 ; ans.a[0][3] = 1 ;
ans.a[1][0] = 1 ; ans.a[1][1] = 0 ; ans.a[1][2] = 0 ; ans.a[1][3] = 0 ;
ans.a[2][0] = 0 ; ans.a[2][1] = 1 ; ans.a[2][2] = 0 ; ans.a[2][3] = 0 ;
ans.a[3][0] = 0 ; ans.a[3][1] = 0 ; ans.a[3][2] = 1 ; ans.a[3][3] = 0 ;
Matrix tmp ;
memset( tmp.a , 0 ,sizeof(tmp.a) );
tmp.a[0][0] = 9 ; tmp.a[1][0] = 6; tmp.a[2][0] = 4 ; tmp.a[3][0] = 2;
Matrix t = quick( ans , n - 4 );
int res = 0 ;
for( int i = 0 ; i < 4 ; i++ ){
res = ( res + t.a[0][i] * tmp.a[i][0] ) % m ;
}
printf("%d\n",res);
}
}
return 0 ;
}