Codeforces1042 E.Vasya and Magic Matrix(期望dp)
題意:
答案對998244353取模。
資料範圍:n,m<=1e3
解法:
題
目
即
一
共
有
n
∗
m
個
三
元
組
(
x
,
y
,
z
)
,
首
先
對
三
元
組
按
z
從
小
到
大
排
序
,
設
第
i
個
三
元
組
為
e
[
i
]
令
d
[
i
]
表
示
從
點
i
開
始
走
可
以
獲
得
的
期
望
總
價
值
,
顯
然
轉
移
方
程
為
:
d
[
i
]
=
1
k
∑
j
=
1
k
{
(
e
[
i
]
.
x
−
e
[
j
]
.
x
)
2
+
(
e
[
i
]
.
y
−
e
[
j
]
.
y
)
2
+
d
[
j
]
}
,
其
中
k
是
[
1
,
i
−
1
]
中
滿
足
e
[
k
]
.
z
<
e
[
i
]
.
z
的
最
大
下
標
.
整
理
轉
移
方
程
:
d
[
i
]
=
1
k
∑
j
=
1
k
{
e
[
i
]
.
x
2
−
2
∗
e
[
i
]
.
x
∗
e
[
j
]
.
x
+
e
[
j
]
.
x
2
+
e
[
i
]
.
y
2
−
2
∗
e
[
i
]
.
y
∗
e
[
j
]
.
y
+
e
[
j
]
.
y
2
+
d
[
j
]
}
=
1
k
{
k
∗
e
[
i
]
.
x
2
+
k
∗
e
[
i
]
.
y
2
+
∑
j
=
1
k
e
[
j
]
.
x
2
+
∑
j
=
1
k
e
[
j
]
.
y
2
−
2
∗
e
[
i
]
.
x
∗
∑
j
=
1
k
e
[
j
]
.
x
−
2
∗
e
[
i
]
.
y
∗
∑
j
=
1
k
e
[
j
]
.
y
+
∑
j
=
1
k
d
[
j
]
}
發
現
維
護
一
下
e
[
j
]
.
x
,
e
[
j
]
.
y
,
e
[
j
]
.
x
2
,
e
[
i
]
.
y
2
,
d
[
j
]
的
前
綴
和
即
可
.
題目即一共有n*m個三元組(x,y,z),\\ 首先對三元組按z從小到大排序,設第i個三元組為e[i]\\ 令d[i]表示從點i開始走可以獲得的期望總價值, 顯然轉移方程為:\\ d[i]=\frac{1}{k}\sum_{j=1}^{k}\{(e[i].x-e[j].x)^2+(e[i].y-e[j].y)^2+d[j]\},\\ 其中k是[1,i-1]中滿足e[k].z<e[i].z的最大下標.\\ 整理轉移方程:\\ d[i]=\frac{1}{k}\sum_{j=1}^{k}\{e[i].x^2-2*e[i].x*e[j].x+e[j].x^2+e[i].y^2-2*e[i].y*e[j].y+e[j].y^2+d[j]\}\\ =\frac{1}{k}\{k*e[i].x^2+k*e[i].y^2+\sum_{j=1}^{k}e[j].x^2+\sum_{j=1}^{k}e[j].y^2-2*e[i].x*\sum_{j=1}^{k}e[j].x-2*e[i].y*\sum_{j=1}^{k}e[j].y+\sum_{j=1}^kd[j]\}\\ 發現維護一下e[j].x,e[j].y,e[j].x^2,e[i].y^2,d[j]的字首和即可.
code:
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int maxm=1e6+5;
const int mod=998244353;
struct Node{
int x,y,z;
}e[maxm];
int inv[maxm];
int ex[maxm];
int ey[maxm];
int ex2[maxm];
int ey2[maxm];
int ds[maxm];
int d[maxm];
int n,m;
int R,C;
int ppow(int a,int b,int mod){
int ans=1%mod;a%=mod;
for(;b;a=a*a%mod,b>>=1)if(b&1)ans=ans*a%mod;
return ans;
}
bool cmp(Node a,Node b){
return a.z<b.z;
}
signed main(){
cin>>n>>m;
int num=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
int x;cin>>x;
e[++num]={i,j,x};
}
}
cin>>R>>C;
sort(e+1,e+1+num,cmp);
for(int i=0;i<=n*m;i++){
inv[i]=ppow(i,mod-2,mod);
}
int j=0;
for(int i=1;i<=num;i++){
while(j+1<i&&e[j+1].z<e[i].z){
j++;
ex[j]=(ex[j-1]+e[j].x)%mod;
ey[j]=(ey[j-1]+e[j].y)%mod;
ex2[j]=(ex2[j-1]+e[j].x*e[j].x)%mod;
ey2[j]=(ey2[j-1]+e[j].y*e[j].y)%mod;
ds[j]=ds[j-1]+d[j];
}
d[i]=(d[i]+j*e[i].x%mod*e[i].x%mod)%mod;
d[i]=(d[i]+j*e[i].y%mod*e[i].y%mod)%mod;
d[i]=(d[i]+ex2[j]+ey2[j])%mod;
d[i]=(d[i]-2*e[i].x*ex[j]%mod)%mod;
d[i]=(d[i]-2*e[i].y*ey[j]%mod)%mod;
d[i]=(d[i]+ds[j])%mod;
d[i]=(d[i]%mod+mod)%mod;
d[i]=d[i]*inv[j]%mod;
if(e[i].x==R&&e[i].y==C){
cout<<d[i]<<endl;
return 0;
}
}
return 0;
}