题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6719
题目大意:

在本题中,我们只有两种方法计算两个n×n的矩阵的乘积,第一种为定义法,需要n3次乘法和(n−1)n2次加法。第二种为Strassen分治法,仅当n为偶数时可以使用,需要18(n/2)2次加法以及再计算7次大小为(n/2)×(n/2)的矩阵的乘积。这7次更小矩阵的乘积也可以选择两种方法之一计算。现假设计算机计算一次加法需要a单位时间,计算一次乘法需要b单位时间,其他任何操作不花费时间,问计算两个n×n的矩阵的乘积至少需要多少时间。输出答案模109+7的余数。

Input
第一行一个正整数t表示数据组数(1≤t≤20)。
每组数据包含一行三个正整数n,a,b(1≤n≤232,n是2的幂,1≤a≤109,1≤b≤109)。

Output 每组数据输出一行,包含一个整数表示答案模109+7的余数。

Sample Input
1
16 1 1

Sample Output
7872

#include <bits/stdc++.h>
#define _int __int128

using namespace std;

inline _int read()
{
    _int x=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9')
    {
        if(ch=='-')
            f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9')
    {
        x=x*10+ch-'0';
        ch=getchar();
    }
    return x*f;
}

inline void write(_int x)
{
    if(x<0)
    {
        putchar('-');
        x=-x;
    }
    if(x>9)
        write(x/10);
    putchar(x%10+'0');
}

_int cf(_int n, _int a, _int b)
{
    _int s1=n*n*n*b+(n-1)*n*n*a;
    if(n%2)
    {
        return s1;
    }
    _int s2=18*(n/2)*(n/2)*a+7*cf(n/2, a, b);

    return min(s1, s2);
}

int main()
{
    int t;
    scanf("%d", &t);
    while(t--)
    {
        _int n = read();
        _int a = read();
        _int b = read();
        write(cf(n, a, b)%1000000007);
        printf("\n");
    }

    return 0;
}
import java.math.BigInteger;
import java.util.Scanner;

public class Main {
    
    static BigInteger s=BigInteger.ONE.add(BigInteger.ONE);
    
    static BigInteger cf(BigInteger n, BigInteger a, BigInteger b) {
        
        BigInteger s1=n.multiply(n).multiply(n).multiply(b).add(n.subtract(BigInteger.ONE).multiply(n).multiply(n).multiply(a));
    
        
        if(n.equals(BigInteger.ONE)) {
            
            return s1;
        }
    
        BigInteger s2=(n.divide(s)).multiply(n.divide(s)).multiply(BigInteger.valueOf(18)).multiply(a).add(cf(n.divide(s),a,b).multiply(BigInteger.valueOf(7)));
        
        return s1.min(s2);
    }
    
    public static void main(String []args) {
        
        Scanner cin=new Scanner(System.in);
        int t;
        t=cin.nextInt();
        while(t-->0) {
            
            BigInteger n, a, b;

            n=cin.nextBigInteger();
            a=cin.nextBigInteger();
            b=cin.nextBigInteger();
            
            System.out.println(cf(n, a, b).remainder(new BigInteger("1000000007")));
        }
    }
}