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;
}

猜你喜欢

转载自blog.csdn.net/weixin_44178736/article/details/112775083