题目大意
题目链接
在本题中,我们只有两种方法计算两个n×n的矩阵的乘积,第一种为定义法,需要n^3
次乘法和(n−1)n^2
次加法。第二种为Strassen分治法,仅当n为偶数时可以使用,需要18 * (n/2) * (n/2)
次加法以及再计算7次大小为(n/2)×(n/2)的矩阵的乘积。这7次更小矩阵的乘积也可以选择两种方法之一计算。现假设计算机计算一次加法需要a单位时间,计算一次乘法需要b单位时间,其他任何操作不花费时间,问计算两个n×n的矩阵的乘积至少需要多少时间。输出答案模1e9 + 7
的余数。
Input
第一行一个正整数t表示数据组数(1≤t≤20)。
每组数据包含一行三个正整数n,a,b(1≤n≤2^32
,n是2的幂,1≤a≤1e9
,1≤b≤1e9
)。
Output
每组数据输出一行,包含一个整数表示答案模109+7的余数。
分析
用__int128直接暴力就行了。
int128模板请戳此
还有比较玄学的东西,
这样写wa了
这样就a了。。。
AC代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
| #include <map>
#include <set>
#include <ctime>
#include <cmath>
#include <queue>
#include <stack>
#include <bitset>
#include <cctype>
#include <cstdio>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <iostream>
#include <algorithm>
#define eps 1e-8
typedef long long ll;
typedef unsigned long long ull;
const int N = 1e6 + 5;
const int INF = 0x3f3f3f3f;
const ll llINF = 0x3f3f3f3f3f3f3f3f;
const ull mod = (ull)1e9 + 7;
ll a, b, n;
__int128 f;
inline void wrii(__int128 x) {
if (x < 0) {
putchar('-');
x = -x;
}
if (x > 9)
wrii(x / 10);
putchar(x % 10 + '0');
}
int main(){
// std::ios::sync_with_stdio(false);
// std::cin.tie(nullptr);
int t;
__int128 i;
std::cin >> t;
while(t--){
std::cin >> n >> a >> b;
f = b;
for (__int128 i = 1; i <= (__int128)n; i <<= 1){
f = std::min((__int128)(i * i * i * b + (i - 1) * i * i * a),
(__int128)((i / 2) * (i / 2) * a * 18 + f * 7));
}
f %= mod;
wrii(f);
std::cout << "\n";
}
return 0;
}
|
1
| 恰似你一低头的温柔,娇弱水莲花不胜寒风的娇羞, 我的心为你悸动不休。 --mingfuyan
|