E. Vasya and Magic Matrix

http://codeforces.com/contest/1042/problem/E

题意:

  一个n*m的矩阵,每个位置有一个元素,给定一个起点,每次随机往一个小于这个点位置走,走过去的值为欧几里得距离的平方,求期望的值。

分析:

  逆推期望。

  将所有值取出,按元素大小排序,然后最小的就是0,往所有大于它的转移即可,复杂度n^2,见下方考试代码。

  考虑每个点,从所有小于它的元素转移。排序后,维护前缀和,可以做到O(1)转移。

  $f[i] = \sum\limits_{j=1,val[j]<val[i]}f[j] + (x_j - x_i)^2 + (y_j - y_i) ^ 2$

  $f[i] =\sum\limits_{j=1,val[j]<val[i]} f[j] + x_j^2 - 2x_jx_i + x_i^2 + y_j^2 - 2y_jy_i + y_i ^ 2$

代码:

 #include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<iostream>
#include<cctype>
#include<set>
#include<vector>
#include<queue>
#include<map>
#define fi(s) freopen(s,"r",stdin);
#define fo(s) freopen(s,"w",stdout);
using namespace std;
typedef long long LL; inline int read() {
int x=,f=;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-;
for(;isdigit(ch);ch=getchar())x=x*+ch-'';return x*f;
} const LL mod = ;
const int N = ; struct Node {
int x, y, val;
bool zh;
bool operator < (const Node &A) const {
return val < A.val;
}
}A[N];
LL f[N], cnt[N], sumx[N], sumy[N], sumx2[N], sumy2[N]; LL ksm(LL a,LL b) {
LL ans = ;
while (b) {
if (b & ) ans = 1ll * ans * a % mod;
a = 1ll * a * a % mod;
b >>= ;
}
return ans;
} inline void add(LL &x,LL y) { (x += y) >= mod ? (x -= mod) : x; }
inline void sub(LL &x,LL y) { (x -= y) < ? (x += mod) : x; } void solve2(int n) { A[].val = -;
for (int i=; i<=n; ++i) {
if (A[i].val == A[i - ].val) cnt[i] = cnt[i - ];
else cnt[i] = i - ;
sumx[i] = (sumx[i - ] + A[i].x) % mod;
sumy[i] = (sumy[i - ] + A[i].y) % mod;
sumx2[i] = (sumx2[i - ] + 1ll * A[i].x * A[i].x % mod) % mod;
sumy2[i] = (sumy2[i - ] + 1ll * A[i].y * A[i].y % mod) % mod;
} LL sum = , tmp = ;
for (int i=; i<=n; ++i) {
LL x2 = sumx2[cnt[i]];
LL y2 = sumy2[cnt[i]];
LL z1 = 1ll * sumx[cnt[i]] * % mod * A[i].x % mod;
LL z2 = 1ll * sumy[cnt[i]] * % mod * A[i].y % mod;
LL h1 = 1ll * cnt[i] * A[i].x % mod * A[i].x % mod;
LL h2 = 1ll * cnt[i] * A[i].y % mod * A[i].y % mod; add(f[i], x2); add(f[i], y2);
sub(f[i], z1); sub(f[i], z2);
add(f[i], h1); add(f[i], h2);
add(f[i], sum); f[i] = 1ll * f[i] * ksm(cnt[i], mod - ) % mod;
if (A[i].zh) {
cout << f[i]; return ;
}
add(tmp, f[i]); // 只有小于的时候才转移!!!
if (A[i].val < A[i + ].val) add(sum, tmp), tmp = ;
} } int main() {
int n = read(), m = read(), tot = ;
for (int i=; i<=n; ++i)
for (int j=; j<=m; ++j)
A[++tot].x = i, A[tot].y = j, A[tot].val = read(), A[tot].zh = false; int x = read(), y = read(), z = (x - ) * m + y;
A[z].zh = true; sort(A + , A + tot + ); solve2(tot);
return ;
}

比赛时代码,记录调试历程。

 #include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<iostream>
#include<cctype>
#include<set>
#include<vector>
#include<queue>
#include<map>
#define fi(s) freopen(s,"r",stdin);
#define fo(s) freopen(s,"w",stdout);
using namespace std;
typedef long long LL; inline int read() {
int x=,f=;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-;
for(;isdigit(ch);ch=getchar())x=x*+ch-'';return x*f;
} const LL mod = ;
const int N = ; struct Node {
int x, y, val;
bool zh;
bool operator < (const Node &A) const {
return val < A.val;
}
}A[N]; LL inv[N], deg[N], f[N];
//double dp[N]; LL ksm(LL a,LL b) {
LL ans = ;
while (b) {
if (b & ) ans = 1ll * ans * a % mod;
a = 1ll * a * a % mod;
b >>= ;
}
return ans;
} LL Calc(int i,int j) {
return ((A[i].x - A[j].x) * (A[i].x - A[j].x) % mod + (A[i].y - A[j].y) * (A[i].y - A[j].y) % mod) % mod;
} void solve1(int n) {
for (int i=; i<=n; ++i) {
// cout << A[i].val << ": ";
if (deg[i]) {
// dp[i] = dp[i] / (double)(deg[i]);
f[i] = 1ll * ksm(deg[i], mod - ) * f[i] % mod;
}
if (A[i].zh) {
cout << f[i]; return ;
}
for (int j=i+; j<=n; ++j)
if (A[j].val > A[i].val) {
// dp[j] = dp[j] + dp[i] + Calc(i, j);
// cout << A[j].val << " " << Calc(i, j) <<"--";
f[j] = (f[j] + f[i] + Calc(i, j)) % mod;
deg[j] ++;
}
// puts("");
}
} int cnt[N], sumx[N], sumy[N], sumx2[N], sumy2[N]; inline void add(LL &x,LL y) { (x += y) >= mod ? (x -= mod) : x; }
inline void sub(LL &x,LL y) { (x -= y) < ? (x += mod) : x; } void solve2(int n) { A[].val = -;
for (int i=; i<=n; ++i) {
if (A[i].val == A[i - ].val) cnt[i] = cnt[i - ];
else cnt[i] = i - ;
sumx[i] = (sumx[i - ] + A[i].x) % mod;
sumy[i] = (sumy[i - ] + A[i].y) % mod;
sumx2[i] = (sumx2[i - ] + 1ll * A[i].x * A[i].x % mod) % mod;
sumy2[i] = (sumy2[i - ] + 1ll * A[i].y * A[i].y % mod) % mod;
} LL sum = , tmp = ;
for (int i=; i<=n; ++i) {
LL x2 = sumx2[cnt[i]];
LL y2 = sumy2[cnt[i]];
LL z1 = 1ll * sumx[cnt[i]] * % mod * A[i].x % mod;
LL z2 = 1ll * sumy[cnt[i]] * % mod * A[i].y % mod;
LL h1 = 1ll * cnt[i] * A[i].x % mod * A[i].x % mod;
LL h2 = 1ll * cnt[i] * A[i].y % mod * A[i].y % mod; add(f[i], x2); add(f[i], y2);
sub(f[i], z1); sub(f[i], z2);
add(f[i], h1); add(f[i], h2);
add(f[i], sum); f[i] = 1ll * f[i] * ksm(cnt[i], mod - ) % mod;
if (A[i].zh) {
cout << f[i]; return ;
}
add(tmp, f[i]); // 只有小于的时候才转移!!!
if (A[i].val < A[i + ].val) add(sum, tmp), tmp = ;
} } int main() {
int n = read(), m = read(), tot = ;
for (int i=; i<=n; ++i)
for (int j=; j<=m; ++j)
A[++tot].x = i, A[tot].y = j, A[tot].val = read(), A[tot].zh = false; int x = read(), y = read(), z = (x - ) * m + y;
A[z].zh = true; sort(A + , A + tot + ); // if (tot <= 1000) {
// solve1(tot) ;return 0;
// }
solve2(tot);
return ;
}

CF 1042 E. Vasya and Magic Matrix的更多相关文章

  1. CF1042E Vasya and Magic Matrix

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

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

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

  3. CF1042E Vasya and Magic Matrix 题解

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

  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. yaml 配置文件

    https://www.cnblogs.com/xinjing-jingxin/p/9128293.html ---文件开始 - 列表 key: val 字典 注意:字典里面可以嵌套字典,列表等.(举 ...

  2. PHP-------抽象和接口

    静态的关键字是:static Class ren { Public static $yanse;    //yanse是一个静态的成员 Static function show() ; // stat ...

  3. 关于mysql 出现 1264 Out of range value for column 错误的解决办法

    今天给客服恢复mysql数据的时候.本来测试好的数据.但是到了客户那里却死活不干活了.老报错! INSERT INTO ka_tan4 set num='716641385999', username ...

  4. JDBC(3)ResultSet

    ResultSet 在执行查询(select)时候使用 这是一个结果对象,该对象包含结果的方法但指针定位到一行时 调用Statement 对象的 executeQuery(sql)可以得到结果集 可以 ...

  5. 【SPJ6285 NGM2 - Another Game With Numbers】 题解

    题目链接:https://www.luogu.org/problemnew/show/SP6285 唉好久之前校内模拟赛的题目 嘴上说着明白但是实现起来我的位运算太丑陋了啊! #include < ...

  6. 2018年暑假ACM个人训练题6 解题报告

    A:水题 https://www.cnblogs.com/yinbiao/p/9311834.html B:考察进制的转化 https://www.cnblogs.com/yinbiao/p/9311 ...

  7. OpenMax的接口与实现

    OpenMax IL层的接口定义由若干个头文件组成,这也是实现它需要实现的内容,它们的基本描述如下所示. OMX_Types.h:OpenMax Il的数据类型定义 OMX_Core.h:OpenMa ...

  8. redhat5本地源NBD驱动安装

    1.将镜像挂载到本机上 1)将系统ISO镜像放到自己电脑/root下     lsb_release -a 查看系统类型 2)在(/)目录下,建立yum目录     mkdir /root/yum 3 ...

  9. 使用js函数格式化xml字符串带缩进

    遇到了一个做soap的API的操作,中途需要说明xml的组装模式等, 如上图,组装产生的mxl代码药格式化并展示.由于是在前端做的,所以需要将字符串将xml进行格式化并输出,找到别人写的算法稍加更改并 ...

  10. show status 查看各种状态

    要查看MySQL运行状态,要优化MySQL运行效率都少不了要运行show status查看各种状态,下面是参考官方文档及网上资料整理出来的中文详细解释: 如有问题,欢迎指正 状态名 作用域 详细解释 ...