社区讨论

提供一个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 条回复,欢迎继续交流。

正在加载回复...