http://uoj.ac/problem/198
(先补一下以前的题解)
这道题5分暴力好写好调,链上部分分可以用可持久化线段树,每次旅行\(x\)值相同的可以用标记永久化线段树。我还听到某些神犇说可以用KD-Treebalabalabala。


很显然\(y,z\)坐标都没用。然后。。。

在一个时空中,对于固定的\(x_0\),要求最小的\(ans=c_i+(x_i-x_0)^2\),拆开可以得到\(ans-x_0^2=(c_i+x_i^2)-2x_ix_0\),这样只需要求\(min_i\{(c_i+x_i^2)-2x_ix_0\}\)。
把\(c_i+x_i^2\)看成\(y\)轴上的截距,\(-2x_i\)看成斜率,相当于一个\(y=kx+b\)的一次函数。在一个时空中有若干个一次函数,我们要求\(x=x_0\)时这些函数的最小值,很明显只要维护一个上凸壳,在上凸壳上查找就可以了。

对每个时空都维护一个上凸壳是必须的,暴力对每个星球所影响的时空都添加一条一次函数时间代价太高了。
还可以把每一部决策都抽象成一棵树,这样一个在第\(i\)个时空中殖民了一个星球,这个星球的一次函数能影响的其他时空是它在决策树中以\(i\)为根的子树。
对决策树的dfs序建线段树,以\(i\)为根的子树在dfs序中构成了一个连续的区间。在线段树上能表示这个区间的节点上都加上一次函数所带来的影响(标记永久化)。
至于放弃殖民的星球,只要记录一下星球在哪个时空中放弃了,线段树update的时候避开这些放弃的时空中的区间就可以了。
那么怎么维护线段树每个节点上的凸壳呢?
splay?复杂度\(O(n\log^2n)\)?
其实只要先对每个星球的\(x\)值从小到大排序,保证加入的一次函数的斜率单调递减,就可以用单调栈维护了,初始化复杂度\(O(n\log n)\)。

对于每个询问,可以直接从线段树的根节点到线段树的叶子节点的路径上所有的节点统计一下\(x=x_0\)时的最小值,最后和地球的值取min。
那么怎么统计一个凸壳上\(x=x_0\)时的最小值呢?
二分?复杂度\(O(n\log^2n)\)?
其实只要对询问的\(x_0\)从小到大排序,这样在凸壳上的位置也是单调递增的,每个凸壳记录上一次在哪里取得最小值,下一次的位置一定在其之后,回答询问时间复杂度\(O(n\log n)\)。

主要采用了离线排序后利用单调性的思想QAQ。

#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N = 500003;ll c0;
struct Edge {int nxt, to;} E[N];
int n, m, cnt = 0, point[N], tmp[N];
vector <int> del[N];void ins(int u, int v) {E[++cnt] = (Edge) {point[u], v}; point[u] = cnt;}struct node {int x; ll c;node(int _x = 0, ll _c = 0) : x(_x), c(_c) {}bool operator < (const node &A) {return x < A.x;}
} Planet[N];int L_dfn[N], R_dfn[N], settle_to[N];void dfs(int x) {L_dfn[x] = ++cnt;for(int i = point[x]; i; i = E[i].nxt)dfs(E[i].to);R_dfn[x] = cnt;
}struct Querynode {int s, x0, id;bool operator < (const Querynode &A) const {return x0 < A.x0;}
} Q[N];ll ans[N];struct Knode {int k; ll b;Knode(int _k = 0, ll _b = 0) : k(_k), b(_b) {}ll cal(int x) {return b + 1ll * k * x;}
};namespace SegmentTree {vector <Knode> Tu[N << 2];int tmp[N << 2];bool Cross(Knode a, Knode b, Knode c) {if (b.k == c.k) return c.b <= b.b;return 1.0 * (b.b - a.b) * (a.k - c.k) > 1.0 * (c.b - a.b) * (a.k - b.k);}void update(int rt, int l, int r, int L, int R, Knode Line) {if (L <= l && r <= R) {if (!Tu[rt].size()) Tu[rt].push_back(Line);else {while (Tu[rt].size() > 1 && Cross(Tu[rt][Tu[rt].size() - 2], Tu[rt].back(), Line)) Tu[rt].pop_back();Tu[rt].push_back(Line);}return;}int mid = (l + r) >> 1;if (L <= mid) update(rt << 1, l, mid, L, R, Line);if (R > mid) update(rt << 1 | 1, mid + 1, r, L, R, Line);}ll query(int rt, int l, int r, int pos, int x) {while (tmp[rt] + 1 < Tu[rt].size() && Tu[rt][tmp[rt]].cal(x) > Tu[rt][tmp[rt] + 1].cal(x)) ++tmp[rt];ll ans = Tu[rt].size() ? Tu[rt][tmp[rt]].cal(x) : 100000000000000000ll;if (l == r) return ans;int mid = (l + r) >> 1;if (pos <= mid) return min(ans, query(rt << 1, l, mid, pos, x));else return min(ans, query(rt << 1 | 1, mid + 1, r, pos, x));}
}ll sqr(int x) {return 1ll * x * x;}
bool cmp_233(int x, int y) {return Planet[x].x < Planet[y].x;}
bool cmp1(int x, int y) {return L_dfn[x] < L_dfn[y];}int main() {scanf("%d%d%lld", &n, &m, &c0);int op, fr, id, x, y, z; ll c;for(int i = 1; i < n; ++i) {tmp[i] = i;scanf("%d%d%d", &op, &fr, &id);if (op == 0) {scanf("%d%d%d%lld", &x, &y, &z, &c);settle_to[id] = i;Planet[id] = node(x, c);} elsedel[id].push_back(i);ins(fr, i);}cnt = 0;dfs(0);Knode Line; int pl, sp;stable_sort(tmp + 1, tmp + n, cmp_233);for(int i = 1; i < n; ++i) if (settle_to[tmp[i]]) {pl = tmp[i];sp = settle_to[pl];Line = Knode(-2 * Planet[pl].x, sqr(Planet[pl].x) + Planet[pl].c);if (!del[pl].size()) {if (L_dfn[sp] <= R_dfn[sp]) SegmentTree::update(1, 1, n, L_dfn[sp], R_dfn[sp], Line);}else {stable_sort(del[pl].begin(), del[pl].end(), cmp1);if (L_dfn[sp] < L_dfn[del[pl][0]]) SegmentTree::update(1, 1, n, L_dfn[sp], L_dfn[del[pl][0]] - 1, Line);if (R_dfn[del[pl].back()] < R_dfn[sp]) SegmentTree::update(1, 1, n, R_dfn[del[pl].back()] + 1, R_dfn[sp], Line);for(int j = 0; j < del[pl].size() - 1; ++j)if (R_dfn[del[pl][j]] + 1 < L_dfn[del[pl][j + 1]]) SegmentTree::update(1, 1, n, R_dfn[del[pl][j]] + 1, L_dfn[del[pl][j + 1]] - 1, Line);}}for(int i = 1; i <= m; ++i) {scanf("%d%d", &Q[i].s, &Q[i].x0);Q[i].id = i;}sort(Q + 1, Q + m + 1);for(int i = 1; i <= m; ++i)ans[Q[i].id] = min(sqr(Q[i].x0) + c0, sqr(Q[i].x0) + SegmentTree::query(1, 1, n, L_dfn[Q[i].s], Q[i].x0));for(int i = 1; i <= m; ++i) printf("%lld\n", ans[i]);return 0;
}


终于AC了

转载于:https://www.cnblogs.com/abclzr/p/6518016.html

【UOJ #198】【CTSC 2016】时空旅行相关推荐

  1. UOJ#198 [CTSC2016]时空旅行

    题目 UOJ#198 [CTSC2016]时空旅行 题解 QAQ允许我做一个悲伤的表情.这题题解真少.我要做一个造福人类的人. 首先呢可以看出,如果把每个时空当做一个节点,这是棵树,每个节点有一个添加 ...

  2. 对话霍金弟子:AI能帮助人类到其他星球进行时空旅行 | AI英雄

    ▼ 点击上方蓝字 关注网易智能 为你解读AI领域大公司大事件,新观点新应用 本文系网易智能工作室(公众号smartman 163)出品,此篇为AI英雄人物第69期. 文 | 小羿 2018年3月31日 ...

  3. 时空旅行(dfs序+线段树分治+斜率优化)

    时空旅行 题意: 给定一棵以000为根的树,每个节点上有信息(一种是增加某个带权三维点,一种是删除某个带权三维点):询问要求从根节点到某个节点的信息总和中找到一个最优带权三维点. 思路: 首先,每个星 ...

  4. bzoj5077: [Ctsc2016]时空旅行【线段树+凸包】

    Description 2045年,人类的技术突飞猛进,已经找到了进行时空旅行的方法.小R得到了一台时空旅行仪,他想用它调查不同 时空中人类的发展状况.根据平行时空理论,宇宙中存在着很多独立的时空,每 ...

  5. 时空旅行的可能性(无聊研究社)

    经济不好的时候,人一般都没有什么爱好,所以这段时间只能以看相对论啊,宇宙起源之类的东西拿来消遣,说实话这类消遣是最廉价的,成本不会高于宅男们欣赏苍老师们的表演的成本.仔细的阅读了一些这些大师们的著作后 ...

  6. 【uoj】198:【CTSC2016】时空旅行-dfs序线段树凸包

    传送门:uoj198 题解 y,z坐标无用. 先化简一下式子,假设选择的是第iii个星球,其x" role="presentation" style="posi ...

  7. uoj 198: [CTSC2016]时空旅行

    一道比较套路的数据结构题.而且写起来也挺顺的. 首先可以发现y和z就是来卖萌的,无视即可.那么考虑一个点(星球)位置为x0,费用为c0,那么询问x到它的总花费为(x-x0)^2+c0=-2x0*x+( ...

  8. 【CTSC2016】时空旅行

    链接 http://uoj.ac/problem/198 题解 首先要发现答案要我们求这个式子: \[ ans=min\bigl((x_i-x)^2+c_i\bigr) \] 显而易见的是这种时空嫁接 ...

  9. uoj198【CTSC2016】时空旅行

    传送门:http://uoj.ac/problem/198 [题解] 首先y.z是没有用的.. 然后式子就是w = (x0-xi)^2+ci的最小值,化出来可以变成一个直线的形式. 然后我们可以用线段 ...

最新文章

  1. JS删除数组指定下标并添加到数组开头
  2. 微信生态增长:裂变与分销讲解
  3. 结构体和typedef
  4. Python-OpenCV 处理图像(五):图像中边界和轮廓检测
  5. ai包装插件_关于DIP异型插件机导入与相关来料标准研究
  6. 基于Delphi API写的UDP通讯类
  7. linux中复制字符串出错,C语言实现字符串的复制的两种方法
  8. struts2 验证框架、国际化
  9. python列表内元素求和_在Python中将列表的每个元素与另一个列表的每个元素相乘/相加/相除的有效方法...
  10. matlab如何绘制传递函数对数幅频特性_开环传递函数是怎样影响系统的?重要参量1/(1+T)与T/(1+T)的释义...
  11. 【JVM】第三章 垃圾收集机制
  12. Press ^C at any time to quit.
  13. JUnit5 断言示例
  14. 20220323:双边沿触发器趣解
  15. Redis 3.0正式版发布,正式支持Redis集群
  16. VC2015解决方案管视图中没有外部依赖项、头文件、源文件、资源文件,提供一个本人解决的办法以及总结网上零零散散的方法给后来者提供一个参考
  17. 用Raspberry Pi作AirPlay服务端
  18. StandardServer.await: create[8005]: java.net.BindException问题原因分析
  19. Huffman编码的Matlab实现--用于单导联ECG数据的压缩和解压缩
  20. 【渝粤题库】广东开放大学 企业文化 形成性考核

热门文章

  1. 全球回报最好的 40 个 VC 投资案例,我们可以从中学到什么?
  2. 如何将nc文件转化为txt格式
  3. Layer visibleRegion的计算过程
  4. 2016年头条校招笔试题
  5. 免费好用的IPv6之远程管理路由器-OpenWrt上uhttpd的使用介绍
  6. 服务器维护灵魂兽刷新吗,抓灵魂兽的各种辛酸,魔兽世界猎人当年抓灵魂兽用过的黑科技漫谈...
  7. 【软件推荐】使用手机和平板作电脑副屏扩展
  8. 基于PHP的大学生问卷调查系统
  9. MySQL深入学习——第六章 查询优化批量导入操作学习笔记
  10. python 实用脚本_python实用脚本红手指导入