zoukankan      html  css  js  c++  java
  • CF1042E Vasya and Magic Matrix 期望 dp

    CF1042E Vasya and Magic Matrix 期望 dp

    链接

    考虑到一个点只能由权值小于它的点转移过来,我们考虑把所有点按照权值排序组成一个序列。

    我们设 (f_i) 表示序列上从第 (i) 点出发的期望得分是多少。那么我们显然有:

    [f_{i}=sumlimits_{a_j<a_i}frac{(x_j-x_i)^2+(y_j-y_i)^2+f_j}{num} ]

    其中,(num) 计数的是所有权值小于 (a_i) 的数。

    我们按照权值分组,把权值相同的分成一组,这样,在每一组中的数只能由前面的数转移过来。

    我们把分子拆开,可以得到:

    [x_j^2-2x_ix_j+x_i^2+y_j^2-2y_jy_i+y_i^2+f_j ]

    显然可以用前缀和维护,可以 (O(1)) 进行转移。

    对于分母的逆元,我们预处理线性求逆元即可。

    不过这个题实现宽泛,及时现求也可以过。

    代码:

    #include<bits/stdc++.h>
    #define dd double
    #define ld long double
    #define ll long long
    #define uint unsigned int
    #define ull unsigned long long
    #define N 1000100
    #define M number
    using namespace std;
    
    const int INF=0x3f3f3f3f;
    const ll mod=998244353;
    
    template<typename T> inline void read(T &x) {
        x=0; int f=1;
        char c=getchar();
        for(;!isdigit(c);c=getchar()) if(c == '-') f=-f;
        for(;isdigit(c);c=getchar()) x=x*10+c-'0';
        x*=f;
    }
    
    struct node{
        int x,y,val;
        inline bool operator < (const node &b) const{
            return val<b.val;
        }
    };
    node a[N];
    
    int n,m,r,c;
    ll num,numx,numy,numx2,numy2;
    ll nownum,nownumx,nownumy,nownumx2,nownumy2;
    ll sumf,nowsumf;
    ll f[N],g[N],ansid,inv[N];
    
    inline ll ksm(ll a,ll b,ll mod){
        ll res=1;
        while(b){
            if(b&1) (res*=a)%=mod;
            a=a*a%mod;
            b>>=1;
        }
        return res;
    }
    
    int main(){
        read(n);read(m);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++){
                int now=(i-1)*m+j;
                read(a[now].val);a[now].x=i;a[now].y=j;
            }
        read(r);read(c);
        sort(a+1,a+n*m+1);
        inv[1]=1;for(int i=2;i<=n*m;i++) inv[i]=(mod-mod/i)*inv[mod%i]%mod;
        for(int i=1;i<=n*m;i++){
            if(a[i].val!=a[i-1].val){
                num+=nownum;numx+=nownumx;numy+=nownumy;
                numx2+=nownumx2;numy2+=nownumy2;
                nownum=nownumx=nownumy=nownumx2=nownumy2=0;
                sumf+=nowsumf;nowsumf=0;
            }
            f[i]=(num*(a[i].x*a[i].x+a[i].y*a[i].y)%mod+numx2+numy2-2*a[i].x*numx%mod-2*a[i].y*numy%mod+sumf)%mod*inv[num]%mod;
            nownum++;nownumx+=a[i].x;nownumy+=a[i].y;nownumx2+=a[i].x*a[i].x;nownumy2+=a[i].y*a[i].y;nowsumf+=f[i];
            nownumx%=mod;nownumy%=mod;nownumx2%=mod;nownumy2%=mod;nowsumf%=mod;
            if(a[i].x==r&&a[i].y==c){ansid=i;break;}
        }
        printf("%lld
    ",f[ansid]);
        return 0;
    }
    
  • 相关阅读:
    Ajax XMLHttpRequest对象的三个属性以及open和send方法
    去空格
    绑定事件中 如可控制函数的执行次数
    我之理解---计时器setTimeout 和clearTimeout
    关于border边框重叠颜色设置问题
    YbtOj练习:二分5 飞离地球
    YbtOj练习:二分4 分割矩阵
    YbtOj练习:二分3 攻击法坛
    YbtOj练习:贪心3 最优密码
    YbtOj练习:二分2 最小时间
  • 原文地址:https://www.cnblogs.com/TianMeng-hyl/p/14986691.html
Copyright © 2011-2022 走看看