社区讨论
提供一个O(log(n+m))的不打表做法
P5023[NOIP 2018 提高组] 填数游戏参与者 9已保存回复 17
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 17 条
- 当前快照
- 1 份
- 快照标识符
- @mi7d73ht
- 此快照首次捕获于
- 2025/11/20 19:45 4 个月前
- 此快照最后确认于
- 2025/11/20 22:10 4 个月前
O(n+m)的做法似乎已经有人说过了,就用那个结论,等比数列快速幂即可。
CPP#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod = 1000000007;
ll modpow(ll a, int b) {
ll res = 1;
for (; b; b >>= 1) {
if (b & 1) res = res * a % mod;
a = a * a % mod;
}
return res;
}
int main() {
int n, m;
scanf("%d%d", &n, &m);
if (n > m) swap(n, m);
if (n == 1) return printf("%lld\n", modpow(2, m)) * 0;
if (n == 2) return printf("%lld\n", modpow(3, m - 1) * 4 % mod) * 0;
ll res = 2LL * modpow(4, n - 2) * modpow(3, m - n) % mod * modpow(2, n - 1) % mod;
if (n == 3) {
if (m == 3) {
res += 12 + 6 + 6;
return printf("%lld\n", res * 2 % mod) * 0;
}
res = (res + 32LL * modpow(3, m - 4)) % mod;
res = (res + 48LL * (modpow(3, m - 4) - 1) % mod * (mod + 1) / 2 + 24) % mod;
res = (res + 16LL * modpow(3, m - 4)) % mod;
return printf("%lld\n", res * 2 % mod) * 0;
}
res = (res + 10LL * modpow(4, n - 4) % mod * modpow(3, m - n) % mod * modpow(2, n - 1)) % mod;
res = (res + 20LL * modpow(3, m - n) % mod * modpow(2, n - 1) % mod * (modpow(4, n - 4) - 1) % mod * (mod + 1) / 3) % mod;
if (n == m) res = (res + 15LL * modpow(2, n - 2)) % mod;
else res = (res + 16LL * modpow(3, m - n - 1) % mod * modpow(2, n - 1) + 12LL * (modpow(2, n - 2) + modpow(2, n - 1) * (modpow(3, m - n - 1) - 1) % mod * (mod + 1) / 2 % mod)) % mod;
res = (res + 20LL * modpow(3, m - n) % mod * modpow(2, n - 1) % mod * (modpow(4, n - 4) - 1) % mod * (mod + 1) / 3) % mod;
if (n == m) res = (res + 15LL * modpow(2, n - 2)) % mod;
else res = (res + 20LL * modpow(3, m - n - 1) % mod * modpow(2, n - 1)) % mod;
return printf("%lld\n", res * 2 % mod) * 0;
return 0;
}
回复
共 17 条回复,欢迎继续交流。
正在加载回复...