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

    感觉不会期望。

    首先把所有格子按照权值从小到大排一下序,这样一共有$n * m$个元素,每个元素有三个属性$x, y, val$。

    下文中的下标均为排序后的下标。

    这样子我们就可以推出公式:

        $f_i = frac{1}{k}sum_{j = 1}^{k}(f_j + (x_j - x_i)^2 + (y_j - y_i)^2)$    $($保证$val_j < val_i$并且这样的元素一共有$k$个$)$。

    暴力转移是$n^2$的,但是我们可以把这个式子拆开:

        $f_i = frac{1}{k}sum_{j = 1}^{k}f_j + x_i^2 + y_i^2 + frac{1}{k}sum_{j = 1}^{k}x_j^2 + frac{1}{k}sum_{j = 1}^{k}y_j^2 - frac{2x_i}{k}sum_{j = 1}^{k}x_j - frac{2y_i}{k}sum_{j = 1}^{k}y_j$

    维护$sum_{i = 1}^{k}x_i^2$、$sum_{i = 1}^{k}y_i^2$、$sum_{i = 1}^{k}y_i$、$sum_{i = 1}^{k}x_i$、$sum_{i = 1}^{k}f_i$五个前缀和就可以$O(n)$转移了。

    要注意$val_i$可能为$0$。

    加上算逆元的时间一共是$O(nmlogP)$。

    Code:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    
    const int N = 1005;
    const int M = 1e6 + 5;
    const ll P = 998244353LL;
    
    int n, m, tot = 0;
    ll a[N][N], f[M];
    
    struct Item {
        ll x, y, val;
    } b[M];
    
    bool cmp(const Item &u, const Item &v) {
        return u.val < v.val;
    }
    
    inline ll fpow(ll x, ll y) {
        ll res = 1LL;
        for(; y > 0; y >>= 1) {
            if(y & 1) res = res * x % P;
            x = x * x % P;
        }
        return res;
    }
    
    inline void up(ll &x, ll y) {
        x = ((x + y) % P + P) % P;
    }
    
    template <typename T>
    inline void read(T &X) {
        X = 0; char ch = 0; T op = 1;
        for(; ch > '9' || ch < '0'; ch = getchar())
            if(ch == '-') op = -1;
        for(; ch >= '0' && ch <= '9'; ch = getchar())
            X = (X << 3) + (X << 1) + ch - 48;
        X *= op;
    }
    
    int main() {
        read(n), read(m);
        for(int i = 1; i <= n; i++) 
            for(int j = 1; j <= m; j++) {
                read(a[i][j]);
                b[++tot].x = 1LL * i, b[tot].y = 1LL * j, b[tot].val = a[i][j];
            }
        
        int stx, sty, pos; read(stx), read(sty);
        sort(b + 1, b + 1 + tot, cmp);
        for(int i = 1; i <= tot; i++)
            if(b[i].x == stx && b[i].y == sty) {
                pos = i;
                break;
            }
        
        ll sumx = 0LL, sumy = 0LL, sumx2 = 0LL, sumy2 = 0LL, sumf = 0LL; int k = 0;
        for(int i = 1; i <= pos; i++) {
            for(; b[k].val < b[i].val && k <= pos; k++) {
                up(sumx, b[k].x), up(sumy, b[k].y);
                up(sumx2, b[k].x * b[k].x % P), up(sumy2, b[k].y * b[k].y % P);
                up(sumf, f[k]);
            }
            if(k <= 1) continue;
            ll invK = fpow(k - 1, P - 2);
            up(f[i], invK * sumf % P);
            up(f[i], b[i].x * b[i].x % P), up(f[i], b[i].y * b[i].y % P);
            up(f[i], invK * sumx2 % P), up(f[i], invK * sumy2 % P);
            up(f[i], -2LL * b[i].x % P * invK % P * sumx % P), up(f[i], -2LL * b[i].y % P * invK % P * sumy % P);
        }
        
        printf("%lld
    ", f[pos]);
        return 0;
    }
    View Code

    提醒自己:写快速幂不要把函数名写成$pow$,因为这样WA了很多次。

  • 相关阅读:
    jQuery.validator.unobtrusive.adapters.addMinMax round trips, doesn't work in MVC3
    Debug a script that sits in a partial view
    OneTrust Cookies
    What's the technical reason for "lookbehind assertion MUST be fixed length" in regex?
    How to specify data attributes in razor, e.g., dataexternalid="23151" on @this.Html.CheckBoxFor(...)
    Google Colab Tips for Power Users
    跟李沐学Ai 04 数据操作 + 数据预处理【动手学深度学习v2】
    使用ActiveReports for .net 进行报表开发(十一)迁移到3.0
    在sqlserver中如何根据字段名查找字段所在的表
    FastCount停止服务,再提供两个免费网站浏览计数器
  • 原文地址:https://www.cnblogs.com/CzxingcHen/p/9680254.html
Copyright © 2011-2022 走看看