题目链接

思路分析

看到题目中 \(n,m \leq 1000\) ,故直接考虑 \(O(n^2)\) 级别做法。

我们先把所有的点按照 \(val\) 值从小到大排序,这样的话二维问题变成序列问题。

设 \(f_i\) 表示走到第 \(i\) 个点的价值的期望。

先列出裸的 \(dp\) 方程:(\(Num\) 表示符合条件的点的个数)

\[f_i =\frac{1}{Num} \sum_{a_i > a_j}(x_i-x_j)^2+(y_i-y_j)^2+f_j
\]

但是这个好像是 \(O(n^2m^2)\) 的优秀算法……

不要担心,我们把式子化简一下:

\[f_i=\frac{1}{Num}\sum_{a_i>a_j}x_i^2+2x_ix_j+x_j^2+y_i^2+2y_iy_j+y_j^2+f_j \\
f_i=\frac{1}{Num}\sum_{a_i>a_j}x_i^2+x_j^2+y_i^2+y_j^2+2(x_ix_j+y_iy_j)+f_j
\]

我们惊喜地发现,可以用前缀和优化。

设:

  • \(suma_i=\sum_{j=1}^ia_j\quad sumb_i=\sum_{j=1}^ib_j\)
  • \(sumpa_i=\sum_{j=1}^ia_j^2 \quad sumpb_i=\sum_{j=1}^ib_j^2\)
  • \(sumf_i=\sum_{j=1}^if_j\)

直接按照上述前缀和替换即可,在这里不写了。

Code

#include <bits/stdc++.h>

#define file(a) freopen(a".in", "r", stdin), freopen(a".out", "w", stdout)

#define Enter putchar('\n')
#define quad putchar(' ') #define int long long #define N 1005
#define mod 998244353 int n, m, a[N][N], tot, x, y, f[N * N], sumf[N * N];
int suma[N * N], sumb[N * N], sumpa[N * N], sumpb[N * N]; struct Node {
int x, y, num;
friend bool operator <(const Node &p, const Node &q) {
return p.num < q.num;
}
}node[N * N]; inline int ksm (int a, int n) {
int ret = 1;
while (n) {
if (n % 2 == 1) ret = (ret * a) % mod;
a = (a * a) % mod;
n /= 2;
}
return ret;
} inline void init() {
for (int i = 1; i <= tot; i++) {
sumpa[i] = (sumpa[i - 1] + node[i].x * node[i].x) % mod;
sumpb[i] = (sumpb[i - 1] + node[i].y * node[i].y) % mod;
suma[i] = (suma[i - 1] + node[i].x) % mod;
sumb[i] = (sumb[i - 1] + node[i].y) % mod;
}
return ;
} inline void solve(int pos, int id) {
// std::cout << pos << " " << id << std::endl;
f[pos] = (f[pos] + sumpa[id] + sumpb[id]) % mod;
f[pos] = f[pos] - 2 * node[pos].x * suma[id] - 2 * node[pos].y * sumb[id];
f[pos] = (f[pos] % mod + mod) % mod;
int px = node[pos].x * node[pos].x;
int py = node[pos].y * node[pos].y;
f[pos] = (f[pos] + id * px + id * py) % mod;
f[pos] = (f[pos] + sumf[id]) % mod;
f[pos] *= ksm(id, mod - 2); f[pos] %= mod;
sumf[pos] = (sumf[pos - 1] + f[pos]) % mod;
return ;
} signed main(void) {
std::cin >> n >> m;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
scanf("%d", &a[i][j]);
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
node[++tot].x = i;
node[tot].y = j;
node[tot].num = a[i][j];
}
}
std::cin >> x >> y;
std::sort(node + 1, node + 1 + tot);
init();
int last;
node[0].num = -114514;
for (int i = 1; i <= tot; i++) {
if (node[i].num != node[i - 1].num) last = i - 1;
solve(i, last);
if (node[i].x == x && node[i].y == y) {
std::cout << f[i] << std::endl;
return 0;
}
}
}

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

  1. CF1042E Vasya and Magic Matrix

    感觉不会期望. 首先把所有格子按照权值从小到大排一下序,这样一共有$n * m$个元素,每个元素有三个属性$x, y, val$. 下文中的下标均为排序后的下标. 这样子我们就可以推出公式: $f_i ...

  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. 【GPLT】 2018年天梯赛全国总决赛 L2-2 小字辈(c++)

    题目: 这一题并不是很难,属于常规的图论遍历题,这里我是用的bfs(dfs应该也可以,但明显bfs简单一些). 本人写的时候写了很多没必要头文件,自己可以根据内容删去,必要的我会写上注释 如有错误,请 ...

  2. Java基础语法Day_02-03(数据类型、运算符、方法、循环结构)

    第5节 数据类型转换 day02_01_数据类型转换_自动转换 day02_02_数据类型转换_强制转换 day02_03_数据类型转换_注意事项 day02_04_ASCII编码表 第6节 运算符 ...

  3. Pytorch Linear ()简单推导

    pytorch,nn.Linear 下图中的A是权重矩阵,b是偏置. in_features输入样本的张量大小 out_features输出样本的张量大小 bias是偏置 # 测试代码 # batch ...

  4. ZooKeeper 到底解决了什么问题?

    点击上方"开源Linux",选择"设为星标" 回复"学习"获取独家整理的学习资料! 目标 ZooKeeper 很流行,有个基本的疑问: Zo ...

  5. 一文详解 FTP、FTPS 与 SFTP 的原理

    开源Linux 长按二维码加关注~ 上一篇:2020年MySQL数据库面试题总结 无论是网盘还是云存储,上传都是一项很简单的操作.那些便捷好用的上传整理工具所用的 FTP 协议到底是什么意义,繁杂的模 ...

  6. Microsoft Graph 的 .NET 6 之旅

    这是一篇发布在dotnet 团队博客上由微软Graph首席软件工程师 Joao Paiva写的文章,原文地址: https://devblogs.microsoft.com/dotnet/micros ...

  7. range内部代码

    def my_range(a, b=None, c=1): if not b: b = a a = 0 while a < b: yield a a += c

  8. 基础路径规划算法(Dijikstra、A*、D*)总结

    引言 在一张固定地图上选择一条路径,当存在多条可选的路径之时,需要选择代价最小的那条路径.我们称这类问题为最短路径的选择问题.解决这个问题最经典的算法为Dijikstra算法,其通过贪心选择的步骤从源 ...

  9. 使用python脚本+zabbix前端监控云联网底层TCP数据流所负载的链路质量,并在丢包时联动保存MTR记录

    背景 目前国内各家云联网跨区域数据传输,会将数据流通过哈希运算负载到不同的底层链路上,而底层链路质量差异较大,这种情况导致的现象就是,使用传统的icmp监控线路正常,但是业务一直不稳定,所以才有了使用 ...

  10. drools规则属性(rule attributes)的使用

    一.介绍 规则属性是您可以添加到业务规则以修改规则行为的附加规范. 在 DRL 文件中,您通常在规则条件和操作的上方定义规则属性,多个属性位于单独的行中,格式如下: rule "rule_n ...