1. 程式人生 > 其它 >Codeforces1042 E.Vasya and Magic Matrix(期望dp)

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]的字首和即可.

nm(x,y,z),z,ie[i]d[i]i,:d[i]=k1j=1k{(e[i].xe[j].x)2+(e[i].ye[j].y)2+d[j]},k[1,i1]滿e[k].z<e[i].z.:d[i]=k1j=1k{e[i].x22e[i].xe[j].x+e[j].x2+e[i].y22e[i].ye[j].y+e[j].y2+d[j]}=k1{ke[i].x2+ke[i].y2+j=1ke[j].x2
+
j=1ke[j].y22e[i].xj=1ke[j].x2e[i].yj=1ke[j].y+j=1kd[j]}e[j].x,e[j].y,e[j].x2,e[i].y2,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; }