[ARC230D] Min Max Matrix
Genius_Star · · 题解
或许更好的阅读体验。
演都不演了?arc 搬原???
思路:
首先不难发现左边恒大于等于右边。
考虑对于
i, j ,有R_i \ge A_{i, j} \ge C_j 。
于是只要右边小于等于左边即可;枚举这个式子的值,设为
直接二维二项式反演一下,容斥钦定有
原题 cf 因为
具体的,注意到后面那个式子是:
令
所以枚举
然后再发现答案关于
完整代码:
#include<bits/stdc++.h>
#define fi first
#define se second
#define lowbit(x) x & (-x)
using namespace std;
typedef long long ll;
const int N = 4e4 + 10, mod = 998244353;
inline ll read(){
ll x = 0, f = 1;
char c = getchar();
while(c < '0' || c > '9'){
if(c == '-')
f = -1;
c = getchar();
}
while(c >= '0' && c <= '9'){
x = (x << 1) + (x << 3) + (c ^ 48);
c = getchar();
}
return x * f;
}
inline void write(ll x){
if(x < 0){
putchar('-');
x = -x;
}
if(x > 9)
write(x / 10);
putchar(x % 10 + '0');
}
inline void getadd(int &x, int y){
x = (x + y >= mod) ? (x + y - mod) : (x + y);
}
inline void getdec(int &x, int y){
x = (x < y) ? (x - y + mod) : (x - y);
}
inline int qpow(int a, int b){
int ans = 1;
while(b){
if(b & 1)
ans = 1ll * ans * a % mod;
a = 1ll * a * a % mod;
b >>= 1;
}
return ans;
}
int T, n, m, w, ans;
int fac[N], ifac[N], p1[N], p2[N], pp[N], y[N];
inline void init(){
fac[0] = fac[1] = 1;
for(int i = 2; i < N; ++i)
fac[i] = 1ll * fac[i - 1] * i % mod;
ifac[N - 1] = qpow(fac[N - 1], mod - 2);
for(int i = N - 2; i >= 0; --i)
ifac[i] = 1ll * (i + 1) * ifac[i + 1] % mod;
}
inline int binom(int n, int m){
return 1ll * fac[n] * ifac[m] % mod * ifac[n - m] % mod;
}
namespace Lacha{
int pre[N], suf[N];
inline int getf(int n, int k){
pre[0] = 1;
for(int i = 1; i <= n; ++i)
pre[i] = 1ll * (k - i + mod) % mod * pre[i - 1] % mod;
suf[n + 1] = 1;
for(int i = n; i >= 0; --i)
suf[i] = 1ll * (k - i + mod) % mod * suf[i + 1] % mod;
int ans = 0, now = 0;
for(int i = 1; i <= n; ++i){
int sum = 1ll * pre[i - 1] * suf[i + 1] % mod * ifac[i - 1] % mod * ifac[n - i] % mod * y[i] % mod;
if((n - i) & 1)
ans = (ans - sum + mod) % mod;
else
ans = (ans + sum) % mod;
}
return ans;
}
};
inline void solve(){
ans = 0;
n = read(), m = read(), w = read();
pp[0] = 1;
for(int i = 1; i <= n; ++i)
pp[i] = 1ll * w * pp[i - 1] % mod;
for(int k = 1; k <= n * m + 2; ++k){
p1[0] = p2[0] = 1;
int a = k, b = w - k + 1;
for(int i = 1; i <= n; ++i)
p1[i] = 1ll * p1[i - 1] * a % mod, p2[i] = 1ll * p2[i - 1] * b % mod;
for(int i = 1; i <= n; ++i){
int A = 1ll * p1[i] * pp[n - i] % mod, B = p2[n - i];
int sum = 1ll * (qpow((A - B + mod) % mod, m) - qpow(A, m) + mod) % mod * binom(n, i) % mod;
if(i & 1)
getdec(ans, sum);
else
getadd(ans, sum);
}
y[k] = ans;
}
write(Lacha::getf(n * m + 2, w));
putchar('\n');
}
int main(){
init();
T = 1;
while(T--)
solve();
return 0;
}