【题目链接】
http://acm.hdu.edu.cn/showproblem.php?pid=6719
在本题中,我们只有两种方法计算两个的矩阵的乘积,第一种为定义法,需要次乘法和次加法。第二种为Strassen分治法,仅当为偶数时可以使用,需要次加法以及再计算次大小为的矩阵的乘积。这次更小矩阵的乘积也可以选择两种方法之一计算。现假设计算机计算一次加法需要单位时间,计算一次乘法需要单位时间,其他任何操作不花费时间,问计算两个的矩阵的乘积至少需要多少时间。输出答案模的余数。
定义法: A * n * n * (n-1) + B * n * n * n
Strassen:A * ( n / 2 ) * ( n / 2 ) * ( n - 1 ) + 7 * Min (定义法(n/2),Strassen(n/2))
C++
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const ll mod = 1e9+7; 5 ll A,B,x; 6 ll Matrix_Mul( ll n ){ 7 n %= mod ; 8 ll t1 = B * n % mod * n % mod * n % mod ; 9 ll t2 = A * n % mod * n % mod * (n-1) % mod ; 10 return ( t1%mod + t2%mod + mod ) % mod ; 11 } 12 13 ll Strassen( ll n ){ 14 if( n&1 ) 15 return Matrix_Mul(n); 16 17 if( n <= 30 * A / (A+B) ) 18 return Matrix_Mul(n); 19 20 ll Half_n = n / 2 ; 21 ll t1 = 18ll * Half_n % mod * Half_n % mod * A % mod ; 22 ll t2 = 7ll * Strassen( Half_n ) % mod ; 23 return ( t1 + t2 + mod ) % mod ; 24 } 25 int main() 26 { 27 ios_base :: sync_with_stdio(false); 28 cin.tie(NULL) , cout.tie(NULL) ; 29 30 int T; 31 cin >> T ; 32 while( T-- ){ 33 cin >> x >> A >> B ; 34 cout << Strassen(x) << endl; 35 } 36 return 0; 37 }
Java
1 import java.math.* ; 2 import java.util.*; 3 import java.security.MessageDigest; 4 public class Main{ 5 6 static BigInteger Zero = new BigInteger ("0"); 7 static BigInteger One = new BigInteger ("1"); 8 static BigInteger Two = new BigInteger ("2") ; 9 static BigInteger Four = new BigInteger ("4") ; 10 static BigInteger Seven = new BigInteger ("7"); 11 static BigInteger Eighteen = new BigInteger ("18") ; 12 static BigInteger Mod = new BigInteger("1000000007"); 13 14 static BigInteger Martirx_Mul( BigInteger n , BigInteger a , BigInteger b ){ 15 BigInteger Step1 = n.multiply(n).multiply(n).multiply(b) ; 16 BigInteger Step2 = n.subtract(One).multiply(n).multiply(n).multiply(a) ; 17 BigInteger Ans = Step1.add(Step2); 18 return Ans; 19 } 20 21 static BigInteger Strassen( BigInteger x , BigInteger a , BigInteger b ){ 22 23 if( x.equals(One) ) 24 return Martirx_Mul( One , a , b ); 25 26 BigInteger Half_x = x.divide(Two); 27 BigInteger Step1 = Eighteen.multiply( Half_x ).multiply(Half_x).multiply( a ); 28 BigInteger Step2 = Seven.multiply( Strassen( Half_x , a ,b ).min(Martirx_Mul(Half_x,a,b)) ) ; 29 BigInteger Mul = Step1.add(Step2); 30 return Mul.min( Martirx_Mul(x,a,b) ); 31 } 32 33 public static void main( String[] args ){ 34 Scanner cin = new Scanner(System.in); 35 int T = cin.nextInt(); 36 while( T -- > 0 ){ 37 BigInteger a,b,n; 38 39 n=cin.nextBigInteger(); 40 a=cin.nextBigInteger(); 41 b=cin.nextBigInteger(); 42 BigInteger ans=Strassen(n,a,b).mod(Mod); 43 System.out.println(ans); 44 } 45 } 46 47 }