题目链接
题目大意:
解题思路:
- 首先我们先把二维矩阵变成一维的
(
x
,
y
)
→
(
x
−
1
)
⋅
m
+
y
(x,y)\rightarrow(x-1)\cdot m+y
(x,y)→(x−1)⋅m+y
- 然后对每个点按照权值排序从小到大去枚举
-
f
[
i
]
=
∑
j
(
x
i
−
x
j
)
2
+
(
y
i
−
y
j
)
2
+
f
[
j
]
m
f[i]=\sum_{j}\frac{(x_i-x_j)^2+(y_i-y_j)^2+f[j]}{m}
f[i]=j∑m(xi−xj)2+(yi−yj)2+f[j]
-
f
[
i
]
是
第
i
个
点
出
发
的
期
望
得
分
f[i]是第i个点出发的期望得分
f[i]是第i个点出发的期望得分
-
m
是
权
值
比
i
小
的
点
的
个
数
m是权值比i小的点的个数
m是权值比i小的点的个数
- 这个式子很不好求
- 我们展开看看
-
m
⋅
x
i
2
+
m
⋅
y
i
2
+
(
x
j
1
2
+
x
j
2
2
.
.
.
.
.
)
+
(
y
j
1
2
+
y
j
2
2
.
.
.
.
.
)
−
2
⋅
(
x
j
1
+
x
j
2
.
.
.
.
.
)
∗
x
i
−
2
⋅
(
y
j
1
+
y
j
2
.
.
.
.
.
)
∗
y
i
+
(
f
[
j
1
]
+
f
[
j
2
]
.
.
.
.
.
)
m\cdot x_i^2+m\cdot y_i^2+(x^2_{j1}+x^2_{j2}.....)+(y^2_{j1}+y^2_{j2}.....)-2\cdot(x_{j1}+x_{j2}.....)*x_i-2\cdot(y_{j1}+y_{j2}.....)*y_i+(f[j1]+f[j2].....)
m⋅xi2+m⋅yi2+(xj12+xj22.....)+(yj12+yj22.....)−2⋅(xj1+xj2.....)∗xi−2⋅(yj1+yj2.....)∗yi+(f[j1]+f[j2].....)
- 我们发现上面的式子可以前缀和预处理的
→
x
2
,
y
2
,
x
,
y
,
f
\rightarrow x^2,y^2,x,y,f
→x2,y2,x,y,f
- 我们还要预处理逆元
AC code
#include <bits/stdc++.h>
#define mid ((l + r) >> 1)
#define Lson rt << 1, l , mid
#define Rson rt << 1|1, mid + 1, r
#define ms(a,al) memset(a,al,sizeof(a))
#define log2(a) log(a)/log(2)
#define lowbit(x) ((-x) & x)
#define IOS std::ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define INF 0x3f3f3f3f
#define LLF 0x3f3f3f3f3f3f3f3f
#define f first
#define s second
#define endl '\n'
using namespace std;
const int N = 2e6 + 10, mod = 998244353;
const int maxn = 2e6 +10;
const long double eps = 1e-5;
const int EPS = 500 * 500;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PII;
typedef pair<ll,ll> PLL;
typedef pair<double,double> PDD;
template<typename T> void read(T &x) {
x = 0;char ch = getchar();ll f = 1;
while(!isdigit(ch)){if(ch == '-')f*=-1;ch=getchar();}
while(isdigit(ch)){x = x*10+ch-48;ch=getchar();}x*=f;
}
template<typename T, typename... Args> void read(T &first, Args& ... args) {
read(first);
read(args...);
}
int n, m, x, y;
int prex2[maxn], prey2[maxn], predp[maxn], dp[maxn], prex[maxn], prey[maxn], inv[maxn];
inline void add(int &x, int y) {
x += y;
if(x >= mod) x -= mod;
if(x < 0) x += mod;
}
struct node {
int x, y;
int val;
bool operator < (const node & a) const {
return val < a.val;
}
}matrix[N];
ll qmi(ll a, ll b) {
int res = 1;
while(b) {
if(b & 1) res = res * a % mod;
a = a * a % mod;
b >>= 1;
}
return res % mod;
}
int main() {
read(n,m);
for(int i = 1; i <= n; ++ i)
for(int last = 1; last <= m; ++ last) {
int val;
cin >> val;
matrix[(i-1)*m+last] = {i,last,val};
}
inv[1] = 1;
for (int i = 2; i <= n * m; ++i) {
inv[i] = (long long)(mod - mod / i) * inv[mod % i] % mod;
}
read(x,y);
sort(matrix+1,matrix+1+n*m);
int last = 0;
for(int i = 1; i <= n * m; ++ i) {
if(matrix[i].val != matrix[i-1].val) last = i-1;
add(dp[i],predp[last]);
add(dp[i],1ll*last*matrix[i].x*matrix[i].x%mod);
add(dp[i],1ll*last*matrix[i].y*matrix[i].y%mod);
add(dp[i],prex2[last]);
add(dp[i],prey2[last]);
add(dp[i],-2ll*prex[last]*matrix[i].x%mod);
add(dp[i],-2ll*prey[last]*matrix[i].y%mod);
dp[i] = 1ll * dp[i] * inv[last] % mod;
if(matrix[i].x == x && matrix[i].y == y) {
cout << (dp[i] % mod + mod) % mod;
return 0;
}
predp[i] = (predp[i-1] + dp[i]) % mod;
prex2[i] = (prex2[i-1] + matrix[i].x*matrix[i].x) % mod;
prey2[i] = (prey2[i-1] + matrix[i].y*matrix[i].y) % mod;
prex[i] = (prex[i-1] + matrix[i].x) % mod;
prey[i] = (prey[i-1] + matrix[i].y) % mod;
}
return 0;
}