CF1585F Non-equal Neighbours 题解
容斥 DP 神仙题 qwq。
考虑容斥,钦定
这样,答案即为:
首先有一个转化,钦定 unique 后剩下最多
有了这个性质,不难得到一个
DP 转移为:
但这样复杂度爆炸,怎么办呢?观察转移方程发现一个性质:第二维下标为
新的转移为:
可这样还是
若
否则,设
综上有:
用前缀和优化即可做到
最后,若
时间复杂度为
Code
#include <cstdio>
#include <stack>
typedef long long ll;
const int n_max = 2e5 + 5;
const ll mod = 998244353;
int a[n_max], n;
ll f[n_max][2], g[n_max][2];
std::stack<int> stk;
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; ++i)
scanf("%d", &a[i]);
f[0][0] = g[0][0] = 1ll;
for (int i = 1; i <= n; ++i) {
while (!stk.empty() && a[stk.top()] >= a[i])
stk.pop();
if (stk.empty()) {
for (int j : {0, 1})
f[i][j] = g[i - 1][j ^ 1] * a[i] % mod;
} else {
for (int j : {0, 1})
f[i][j] = (f[stk.top()][j] + (g[i - 1][j ^ 1] - g[stk.top() - 1][j ^ 1]) * a[i] % mod) % mod;
}
for (int j : {0, 1})
g[i][j] = (g[i - 1][j] + f[i][j]) % mod;
stk.push(i);
}
int sgn = (n & 1) ? -1 : 1;
printf("%lld\n", ((f[n][0] - f[n][1]) * sgn % mod + mod) % mod);
return 0;
}