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. IM

    一.IM技术概念 IM技术全称Instant Messaging,中文翻译"即时通讯",它是一种使人们能在网上识别在线用户并与他们实时交换消息的技术,是电子邮件发明以来迅速崛起的在 ...

  2. Codeforces Round #434 (Div. 2)【A、B、C、D】

    Codeforces Round #434 (Div. 2) codeforces 858A. k-rounding[水] 题意:已知n和k,求n的最小倍数x,要求x后缀至少有k个0. 题解:答案就是 ...

  3. Github 删除 repository

    Github 删除 repository 如下图操作

  4. BZOJ3999:[TJOI2015]旅游(树链剖分)

    Description 为了提高智商,ZJY准备去往一个新世界去旅游.这个世界的城市布局像一棵树.每两座城市之间只有一条路径可 以互达.每座城市都有一种宝石,有一定的价格.ZJY为了赚取最高利益,她会 ...

  5. [HNOI2007]紧急疏散EVACUATE

    嘟嘟嘟 看数据范围,第一反应觉得爆搜是不是能骗点分,但发现爆搜太难写了,于是就开始想想正解…… 正解大概猜到了是网络流,但是怎么把时间这个条件加入到图的内容中,却困扰了我好半天,总是感觉把这种不同维度 ...

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

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

  7. Servlet映射的过程

    1.首先通过上图 locolhost:8080/login.html 访问到这个登录的html页 2 通过html页的 action="LoginServlet" 进行映射,所以填 ...

  8. Unity中自定义扩展方法

    问题背景 在使用unity开发过程中,通常会遇到一种情况,比如说给物体重新赋值坐标的问题, Transfrom tran: ,pos_y=,pos_z=; tran.position=new Vect ...

  9. ORM优缺点

    优点: 1.提高了开发效率.由于ORM可以自动对Entity对象与数据库中的Table进行字段与属性的映射,所以我们实际可能已经不需要一个专用的.庞大的数据访问层. 2.ORM提供了对数据库的映射,不 ...

  10. 第25章 串行FLASH文件系统FatFs

    25.1  文件系统 即使读者可能不了解文件系统,读者也一定对“文件”这个概念十分熟悉.数据在PC上是以文件的形式储存在磁盘中的,这些数据的形式一般为ASCII码或二进制形式.在上一章我们已经写好了Q ...