感觉不会期望。

首先把所有格子按照权值从小到大排一下序,这样一共有$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 = ;
const int M = 1e6 + ;
const ll P = 998244353LL; int n, m, tot = ;
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 > ; y >>= ) {
if(y & ) 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 = ; char ch = ; T op = ;
for(; ch > '' || ch < ''; ch = getchar())
if(ch == '-') op = -;
for(; ch >= '' && ch <= ''; ch = getchar())
X = (X << ) + (X << ) + ch - ;
X *= op;
} int main() {
read(n), read(m);
for(int i = ; i <= n; i++)
for(int j = ; 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 + , b + + tot, cmp);
for(int i = ; 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 = ;
for(int i = ; 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 <= ) continue;
ll invK = fpow(k - , P - );
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\n", f[pos]);
return ;
}

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

CF1042E Vasya and Magic Matrix的更多相关文章

  1. CF1042E Vasya and Magic Matrix 题解

    题目链接 思路分析 看到题目中 \(n,m \leq 1000\) ,故直接考虑 \(O(n^2)\) 级别做法. 我们先把所有的点按照 \(val\) 值从小到大排序,这样的话二维问题变成序列问题. ...

  2. CF 1042 E. Vasya and Magic Matrix

    E. Vasya and Magic Matrix http://codeforces.com/contest/1042/problem/E 题意: 一个n*m的矩阵,每个位置有一个元素,给定一个起点 ...

  3. Vasya and Magic Matrix CodeForces - 1042E (概率dp)

    大意:给定n*m矩阵, 初始位置(r,c), 每一步随机移动到权值小于当前点的位置, 得分为移动距离的平方, 求得分期望. 直接暴力dp的话复杂度是O(n^4), 把距离平方拆开化简一下, 可以O(n ...

  4. Educational Codeforces Round 9 F. Magic Matrix 最小生成树

    F. Magic Matrix 题目连接: http://www.codeforces.com/contest/632/problem/F Description You're given a mat ...

  5. Educational Codeforces Round 48 (Rated for Div. 2) D 1016D Vasya And The Matrix (构造)

    D. Vasya And The Matrix time limit per test 2 seconds memory limit per test 256 megabytes input stan ...

  6. codeforces1016 D. Vasya And The Matrix(思维+神奇构造)

    D. Vasya And The Matrix time limit per test 2 seconds memory limit per test 256 megabytes input stan ...

  7. Codeforces 632F Magic Matrix(bitset)

    题目链接  Magic Matrix 考虑第三个条件,如果不符合的话说明$a[i][k] < a[i][j]$ 或 $a[j][k] < a[i][j]$ 于是我们把所有的$(a[i][j ...

  8. D. Vasya And The Matrix(Educational Codeforces Round 48)

    D. Vasya And The Matrix time limit per test2 seconds memory limit per test256 megabytes inputstandar ...

  9. Vasya And The Matrix CodeForces - 1016D (思维+构造)

    Now Vasya is taking an exam in mathematics. In order to get a good mark, Vasya needs to guess the ma ...

随机推荐

  1. P2455 [SDOI2006]线性方程组

    P2455 [SDOI2006]线性方程组 真\(\cdot\)高斯消元模板题 由于各种hack数据被造出来~码量突增~,其实也就多了二三十行 将每行系数消到最多有一个非0数 特殊情况: 在过程同时 ...

  2. 开发rsync启动脚本

    rsync rsync是类unix系统下的数据镜像备份工具——remote sync.一款快速增量备份工具 Remote Sync,远程同步 支持本地复制,或者与其他SSH.rsync主机同步.   ...

  3. 算法(Algorithms)第4版 练习 1.5.6

    对于weighted quick-union,对每个输入数据对,其最大的循环次数为lgN(sites) 故对于109 sites和106 input pairs,其总的指令次数为:sum = lg10 ...

  4. linux开机过程

    一.MBR(main boot record)主引导记录 主引导记录位于0盘面,0磁道,0扇区,早期由512个字节组成. 其中446个字节是boot loader程序.Boot Loader是在操作系 ...

  5. JavaScript秘密

    对象 对象使用和属性 JavaScript 中所有变量都可以当作对象使用,除了两个例外 null 和 undefined. false.toString(); // 'false' [1, 2, 3] ...

  6. php 二维数组验证一个值是否存在

    php 判断数字在二维数组里 $arr = array( array('a', 'b'), array('c', 'd') ); in_array('a', $arr); // 此时返回的永远都是 f ...

  7. nodejs buffer 总结

    JavaScript 语言自身只有字符串数据类型,没有二进制数据类型.Buffer 类,该类用来创建一个专门存放二进制数据的缓存区. 一个 Buffer 类似于一个整数数组,但它对应于 V8 堆内存之 ...

  8. 【leetcode刷题笔记】Gas Station

    There are N gas stations along a circular route, where the amount of gas at station i is gas[i]. You ...

  9. php中socket的使用

    php中使用socket在服务器端主要使用这么几个函数: 1/$socket = socket_create(AF_INET,SOCK_STREAM,SOL_TCP)创建一个socket 2/sock ...

  10. uoj problem 10

    uoj problem 10 题目大意: 给定任务若干,每个任务在\(t_i\)收到,需要\(s_i\)秒去完成,优先级为\(p_i\) 你采用如下策略: 每一秒开始时,先收到所有在该秒出现的任务,然 ...