LibreOJ #2009. 「SCOI2015」小凸玩密室
Posted ZlycerQan
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LibreOJ #2009. 「SCOI2015」小凸玩密室相关的知识,希望对你有一定的参考价值。
二次联通门 : LibreOJ #2009. 「SCOI2015」小凸玩密室
/* LibreOJ #2009. 「SCOI2015」小凸玩密室 树形dp 做到这么正常的题突然感觉好不适应。。。。 考虑转移 f[x][y] 表示从x点转移到y点的代价 则我们需要处理出以x为根的子树的代价 讨论处理一下即可(有没有左儿子,有没有右儿子,或是都有) 但是这样转移是O(N^2)的 所以我们考虑优化 显然有很多转移是不需要的 比如y在x的子树中时就没必要转移 那么考虑优化 设g[x][i]表示走完x的子树再走到x的深度为i的祖先的最小代价 那么在讨论一下处理就好(看代码里的方程应该很好理解) 统计时就是枚举点,统计父亲,兄弟, 然后父亲的父亲,兄弟。。 更新答案即可 */ #include <cstdio> #include <iostream> const int BUF = 12312312; char Buf[BUF], *buf = Buf; typedef long long LL; using std :: min; inline void read (int &now) { for (now = 0; !isdigit (*buf); ++ buf); for (; isdigit (*buf); now = now * 10 + *buf - ‘0‘, ++ buf); } #define Max 200010 LL f[Max][Max / 10000], g[Max][Max / 10000]; LL deep[Max], d[Max]; int key[Max]; int v[Max]; int Main () { freopen ("1.in", "r", stdin); fread (buf, 1, BUF, stdin); int N, z; read (N); register int i, j; for (i = 1; i <= N; ++ i) read (key[i]); for (i = 2, deep[1] = 1; i <= N; ++ i) { read (z), d[i] = d[i >> 1] + z; deep[i] = deep[i >> 1] + 1, v[i] = z; } LL l, r, y; register LL x; LL res; for (x = N; x; -- x) for (i = 0; i < deep[x]; ++ i) { l = x << 1, r = l | 1; y = (x >> (deep[x] - i - 1)) ^ 1; if (l > N) f[x][i] = key[y] * (d[x] + d[y] - (d[y >> 1] << 1)); else if (r > N) f[x][i] = key[l] * v[l] + f[l][i]; else f[x][i] = min (key[l] * v[l] + f[r][i] + f[l][deep[x]], key[r] * v[r] + f[l][i] + f[r][deep[x]]); } for (x = N; x; -- x) for (i = 0; i <= deep[x]; ++ i) { l = x << 1, r = l | 1; y = x >> (deep[x] - i); if (l > N) g[x][i] = key[y] * (d[x] - d[y]); else if (r > N) g[x][i] = g[l][i] + key[l] * v[l]; else g[x][i] = min (key[l] * v[l] + f[l][deep[l] - 1] + g[r][i], key[r] * v[r] + f[r][deep[r] - 1] + g[l][i]); } LL Answer = g[1][0]; LL pos; for (i = 2; i <= N; ++ i) { res = g[i][deep[i] - 1], pos = i; for (; pos != 1; pos >>= 1) { y = pos ^ 1, z = pos >> 1; if (y > N) res += key[z >> 1] * v[z]; else res += key[y] * v[y] + g[y][deep[z] - 1]; } Answer = min (Answer, res); } printf ("%lld", Answer); return 0; } int ZlycerQan = Main (); int main (int argc, char *argv[]) {;}
以上是关于LibreOJ #2009. 「SCOI2015」小凸玩密室的主要内容,如果未能解决你的问题,请参考以下文章
LibreOJ #2006. 「SCOI2015」小凸玩矩阵
AC日记——「SCOI2015」情报传递 LiBreOJ 2011
AC日记——「SCOI2015」国旗计划 LiBreOJ 2007