CF1837E
这是一道非常有意思的题。
设
下面对于每个队伍的“数值”不是编号,而是能力。(比如说这时编号为
思路清晰的,我们发现在初始状态下,每两格一组,每组之间是互相独立的。然后我们当前已经确定了一些队伍的位置,只知道这些发现很难去计算答案,因为这一次竞选完的队伍之后还有顺序要求,所以我们得到的性质仍然不够。
经过观察就会发现,每一组只可能有一个能力小于等于
我们设一个函数,
其中
接着想办法求转移系数,实际上就是当前这一轮要被淘汰的队伍的位置方案,其实比较好求,设
接下来就是实现问题,运用乘法交换律,发现不需要真的去递归,直接循环就可以了。
代码:
#include <bits/stdc++.h>
#define int long long
#define rep(i, l, r) for(int i = l; i <= r; ++ i)
#define rrp(i, l, r) for(int i = r; i >= l; -- i)
#define pii pair <int, int>
#define eb emplace_back
using namespace std;
constexpr int N = 6e5 + 5, P = 998244353;
typedef long long ll;
inline int rd ()
{
int x = 0, f = 1;
char ch = getchar ();
while (! isdigit (ch)) { if (ch == '-') f = -1; ch = getchar (); }
while (isdigit (ch)) { x = (x << 1) + (x << 3) + ch - 48; ch = getchar (); }
return x * f;
}
int n, m, a[N], b[2][N];
int fac[N], inv[N];
int qpow (int x, int y)
{
int ret = 1;
for (; y; y >>= 1, x = x * x % P)
if (y & 1) ret = ret * x % P;
return ret;
}
void add (int &x, int y) { (x += y) >= P && (x -= P); }
int A (int n, int m) { return fac[n] * inv[n - m] % P; }
auto main () -> signed
{
// freopen ("1.in", "r", stdin);
// freopen ("1.out", "w", stdout);
m = rd (); n = 1ll << m; rep (i, 1, n) a[i] = b[0][i] = rd ();
rep (i, 1, n) if (b[0][i] < 0) b[0][i] = 1e9; else b[0][i] = n - b[0][i] + 1;
fac[0] = 1;
rep (i, 1, n) fac[i] = fac[i - 1] * i % P;
inv[n] = qpow (fac[n], P - 2); inv[0] = 1;
rrp (i, 1, n - 1) inv[i] = inv[i + 1] * (i + 1) % P;
int ret = 1, p = 0; while (n > 1)
{
int Mi = n >> 1, tot = 0, sum = Mi;
rep (i, 2, n) if (b[p][i] <= Mi && b[p][i - 1] <= Mi)
return puts ("0"), 0; else ++ i;
rep (i, 2, n)
if (b[p][i] < 1e9 && b[p][i - 1] < 1e9)
if (b[p][i] > Mi && b[p][i - 1] > Mi) return puts ("0"), 0;
else ++ i; else ++ i;
int tmp = 1; rep (i, 1, n) tot += (b[p][i] <= Mi); rep (i, 1, n) {
++ i; if (b[p][i] >= 1e9 && b[p][i - 1] >= 1e9) add (tmp, tmp);
} ret = (ret * tmp % P * fac[Mi - tot] % P);
rep (i, 1, Mi)
{
b[p ^ 1][i] = max (b[p][(i << 1) - 1], b[p][i << 1]);
if (b[p ^ 1][i] >= 1e9)
{
if (b[p][(i << 1) - 1] < 1e9 && b[p][(i << 1) - 1] > Mi)
b[p ^ 1][i] = b[p][(i << 1) - 1];
if (b[p][i << 1] < 1e9 && b[p][i << 1] > Mi)
b[p ^ 1][i] = b[p][i << 1];
} if (b[p ^ 1][i] < 1e9) b[p ^ 1][i] -= Mi;
} p = ! p; n >>= 1;
} printf ("%lld\n", ret);
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?