传送门:http://uoj.ac/problem/198

【题解】

首先y、z是没有用的。。

然后式子就是w = (x0-xi)^2+ci的最小值,化出来可以变成一个直线的形式。

然后我们可以用线段树维护dfs序上的每个点。

每个点维护经过这个点的所有直线(标记永久化),也就是维护上凸壳。

然后我们把询问按照x排序,每次决策点只会后移。所以复杂度就有保证啦!

真**难写

还有一个十分有趣的事实啊

我用一个号交完ac在另一个号再交就RE了啊。。。

不管了反正过了

# include <vector>
# include <stdio.h>
# include <string.h>
# include <algorithm>
// # include <bits/stdc++.h>using namespace std;typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
const int M = 5e5 + 10;
const int mod = 1e9+7;# define RG register
# define ST staticint n, q, s[M], ps[M];
ll c0, ans[M];
vector<int> b[M];
struct planet {int x; ll c;planet() {}planet(int x, ll c) : x(x), c(c) {}friend bool operator < (planet a, planet b) {return a.x<b.x;}
}p[M];struct line {ll k, b;line() {}line(ll k, ll b) : k(k), b(b) {}inline ll set(int x) {return k*(ll)x+b;}
};struct quest {int s, x0, id;quest() {}quest(int s, int x0, int id) : s(s), x0(x0), id(id) {}friend bool operator < (quest a, quest b) {return a.x0<b.x0;}
}qu[M];int head[M], nxt[M], to[M], tot, in[M], out[M], DFN;
inline void add(int u, int v) {++tot; nxt[tot] = head[u]; head[u] = tot; to[tot] = v;
}inline void dfs(int x) {in[x] = ++DFN;for (int i=head[x]; i; i=nxt[i]) dfs(to[i]);out[x] = DFN;
}inline bool cmp(int x, int y) {return p[x].x<p[y].x;
}inline bool cmp_b(int x, int y) {return in[x] < in[y];
}namespace SMT {const int M = 2e6 + 10;vector<line> w[M];int lst[M];inline bool canout(line a, line b, line c) {if(b.k == c.k) return b.b >= c.b;return 1.0*(b.b-a.b)*(a.k-c.k) > 1.0*(c.b-a.b) * (a.k-b.k);}inline void change(int x, int l, int r, int L, int R, line add) {if(L <= l && r <= R) {if(w[x].size()) {while(w[x].size() > 1 && canout(w[x][w[x].size()-2], w[x][w[x].size()-1], add)) w[x].pop_back();w[x].push_back(add);} else w[x].push_back(add);return ;}int mid = l+r>>1;if(L <= mid) change(x<<1, l, mid, L, R, add);if(R > mid) change(x<<1|1, mid+1, r, L, R, add);}inline ll query(int x, int l, int r, int pos, int x0) {while(lst[x]+1 < w[x].size() && w[x][lst[x]].set(x0) > w[x][lst[x]+1].set(x0)) ++lst[x];ll cur = (w[x].size() ? w[x][lst[x]].set(x0) : 1e18);if(l == r) return cur;int mid = l+r>>1;if(pos <= mid) return min(cur, query(x<<1, l, mid, pos, x0));else return min(cur, query(x<<1|1, mid+1, r, pos, x0));}inline void change(int L, int R, line add) {if(L>R) return;change(1, 1, DFN, L, R, add);}inline ll query(int pos, int x0) {return query(1, 1, DFN, pos, x0); }
}int main() {scanf("%d%d%lld", &n, &q, &c0);for (int i=1, op, fr, id, x, c; i<n; ++i) {ps[i] = i;scanf("%d%d%d", &op, &fr, &id);if(op == 0) {scanf("%d%*d%*d%lld", &x, &c);s[id] = i;p[id] = planet(x, c);} else b[id].push_back(i);add(fr, i);}dfs(0);sort(ps+1, ps+n, cmp);for (int i=1, t; i<n; ++i) {if(s[ps[i]]) {int id = ps[i], se = s[id];line L = line(-2ll*p[id].x, 1ll*p[id].x*p[id].x+p[id].c);if(b[id].size()) {sort(b[id].begin(), b[id].end(), cmp_b);t = b[id].size();SMT::change(in[se], in[b[id][0]]-1, L);SMT::change(out[b[id][t-1]]+1, out[se], L);for (int j=1; j<t; ++j)SMT::change(out[b[id][j-1]]+1, in[b[id][j]]-1, L);} else SMT::change(in[se], out[se], L);}}for (int i=1; i<=q; ++i) {scanf("%d%d", &qu[i].s, &qu[i].x0);qu[i].id=i;}sort(qu+1, qu+q+1);for (int i=1; i<=q; ++i)ans[qu[i].id] = 1ll * qu[i].x0 * qu[i].x0 + min(c0, SMT::query(in[qu[i].s], qu[i].x0));for (int i=1; i<=q; ++i) printf("%lld\n", ans[i]);return 0;
}

View Code

转载于:https://www.cnblogs.com/galaxies/p/uoj198.html

uoj198【CTSC2016】时空旅行相关推荐

  1. [UOJ198][CTSC2016]时空旅行

    uoj description 你要维护若干个集合,每个集合都是有一个编号比他小的集合扩展而来,扩展内容为加入一个新的元素\((x,c)\)或者删除一个已有元素.集合的扩展关系之间构成一个树形结构. ...

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

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

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

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

  4. [CTSC2016]时空旅行(斜率优化+线段树分治)

    洛谷题目传送门 解题思路 首先发现只有xxx和ccc是有用的 这些时空构成了一棵树,我们实际上要找一个点iii,满足对于给出的XXX min((X−xi)2+ci)min((X-x_i)^2+c_i) ...

  5. [CTSC2016]时空旅行

    一.题目 点此看题 二.解法 可以看出这些平行时空呈树形结构,每个星球都会出现在一段连续的dfndfndfn序中,而我们正是要对每个时空的星球中找最小值,那么可以把星球打在dfndfndfn的线段树上 ...

  6. BZOJ5077: [Ctsc2016]时空旅行(线段树+凸包)

    传送门 题解: 首先答案为min(x−xi)2+cimin(x−xi)2+ci\min {(x-x_i)^2+c_i},移项得x2−2xix+x2i+cx2−2xix+xi2+cx^2 -2x_ix+ ...

  7. [CTSC2016]时空旅行 (线段树分治)

    前言 昨天学习了线段树分治,算法比较抽象,没有学得太具体,今天做一道例题练练手 --自闭前 题面上洛谷 题意 维护若干个集合,每个集合都是由一个编号比它小的集合加入一个二元组(x,c)(x,c)(x, ...

  8. CTSC2016时空旅行

    当时看这道题AC的人数比较多,就开了这道题. 很容易发现是这是一个有关凸包的题. 然后不知道怎么维护凸包,一直在想cdq,感觉复杂度不行,于是被这玩意难住了-- 幸好有亲学长yyh造福人类的题解:ht ...

  9. Luogu P5416 [CTSC2016]时空旅行

    题目 简化题意:你需要维护\(n\)个集合,集合元素为二元组\((x,v)\).集合\(i\)的产生方式是以某个原有集合\(p_i\)为样本,扩展或删除一个元素后得到新集合.有\(q\)次询问,每次给 ...

  10. [CTSC2016]时空旅行(线段树+凸包)

    应该是比较套路的,但是要A掉仍然不容易. 下面理一下思路,思路清楚了也就不难写出来了. 0.显然y,z坐标是搞笑的,忽略即可. 1.如果x不变,那么直接set即可解决. 2.考虑一个空间和询问x0,通 ...

最新文章

  1. nodejs 中间件 反向代理 接口转发
  2. 我的面试(四)补充1
  3. 删除链表中重复的结点
  4. 十秒解决开发环境跨域问题——取消浏览器同源策略
  5. 一次回母校教前端的经历
  6. mysql 8安装 windows xp_postgreSQL[Windows XP]安装问题解决方案:
  7. 基于canvas的前端图片压缩
  8. PN结、二极管原理详解与应用
  9. 夜神模拟器和appium 的安装
  10. matlab非齐次方程组的通解,用matlab求非齐次线性方程组的通解?
  11. 防水穿墙套管在建筑外墙管道需设置柔性连接
  12. c语言int【】=(123456789) 元素a【】的值,算法-用C语言实现
  13. 实现金钱数字格式化:一行代码解决(三位分隔)
  14. 计算机网络中速率和带宽的区别
  15. 使计算机无法启动的病毒是,0xc0000017蓝屏计算机无法启动解决方案
  16. 周年更名,元宇宙产业委再上新台阶
  17. onsubmit阻止表单提交的一种方式
  18. <二> objectARX开发:创建和编辑基本图形对象
  19. 慢节奏的和府,能否掌握资本带来的“加速度”
  20. 前50%股票成交量占比计算

热门文章

  1. LPC1768的P0.27,P0.28管脚作为GPIO口输出需要外接上拉电阻才能输出高电平
  2. 资深投资人全力反击: VC增值平台从来就不是一坨狗屎
  3. 前端sku-spu详解
  4. 数码宝贝 皇家骑士团(奥米加兽、金甲龙兽、红莲骑士兽、杜纳斯兽、剑皇兽、究极V龙兽、阿尔法兽、颅骨兽、八足马兽、芳香兽、艾可萨兽、顽固兽、杰斯兽)
  5. 北京大学可视化发展前沿暑期学校第四讲
  6. CANopen总线的高级协议详解
  7. 为打造无人仓,菜鸟自研了一套柔性自动化技术
  8. 支持移动触摸设备的简洁js幻灯片插件
  9. 我读经典(5):读《大话重构》迷你书有感
  10. 修改自己电脑连接的路由器的配置网址192.168.1.1