uoj198【CTSC2016】时空旅行
【题解】
首先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 + ;
const int mod = 1e9+; # define RG register
# define ST static int 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 + ;
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() > && canout(w[x][w[x].size()-], w[x][w[x].size()-], add)) w[x].pop_back();
w[x].push_back(add);
} else w[x].push_back(add);
return ;
}
int mid = l+r>>;
if(L <= mid) change(x<<, l, mid, L, R, add);
if(R > mid) change(x<<|, mid+, r, L, R, add);
} inline ll query(int x, int l, int r, int pos, int x0) {
while(lst[x]+ < w[x].size() && w[x][lst[x]].set(x0) > w[x][lst[x]+].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>>;
if(pos <= mid) return min(cur, query(x<<, l, mid, pos, x0));
else return min(cur, query(x<<|, mid+, r, pos, x0));
} inline void change(int L, int R, line add) {
if(L>R) return;
change(, , DFN, L, R, add);
}
inline ll query(int pos, int x0) {
return query(, , DFN, pos, x0);
}
} int main() {
scanf("%d%d%lld", &n, &q, &c0);
for (int i=, op, fr, id, x, c; i<n; ++i) {
ps[i] = i;
scanf("%d%d%d", &op, &fr, &id);
if(op == ) {
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();
sort(ps+, ps+n, cmp);
for (int i=, 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][]]-, L);
SMT::change(out[b[id][t-]]+, out[se], L);
for (int j=; j<t; ++j)
SMT::change(out[b[id][j-]]+, in[b[id][j]]-, L);
} else SMT::change(in[se], out[se], L);
}
}
for (int i=; i<=q; ++i) {
scanf("%d%d", &qu[i].s, &qu[i].x0);
qu[i].id=i;
}
sort(qu+, qu+q+);
for (int i=; 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=; i<=q; ++i) printf("%lld\n", ans[i]);
return ;
}
uoj198【CTSC2016】时空旅行的更多相关文章
- [UOJ198][CTSC2016]时空旅行
uoj description 你要维护若干个集合,每个集合都是有一个编号比他小的集合扩展而来,扩展内容为加入一个新的元素\((x,c)\)或者删除一个已有元素.集合的扩展关系之间构成一个树形结构. ...
- Luogu P5416 [CTSC2016]时空旅行
第一次写线段树分治的题目,没想到是道这么毒的题233 首先发现题目里的\((x,y,z,c)\)就是在放屁,只有\((x,c)\)是有用的 因此我们可以把题意转化为,在某一个时间节点上,求出所有元素的 ...
- [CTSC2016]时空旅行
description 题面 solution 线段树分治+斜率优化毒瘤题 题目可以简化为: 你要维护一个包含元素\((x,c)\)的集合 修改操作为从以前的一个版本更新,修改内容为添加或删除一个元素 ...
- [CTSC2016]时空旅行(线段树+凸包)
应该是比较套路的,但是要A掉仍然不容易. 下面理一下思路,思路清楚了也就不难写出来了. 0.显然y,z坐标是搞笑的,忽略即可. 1.如果x不变,那么直接set即可解决. 2.考虑一个空间和询问x0,通 ...
- CTSC2016时空旅行
当时看这道题AC的人数比较多,就开了这道题. 很容易发现是这是一个有关凸包的题. 然后不知道怎么维护凸包,一直在想cdq,感觉复杂度不行,于是被这玩意难住了…… 幸好有亲学长yyh造福人类的题解:ht ...
- @loj - 2987@ 「CTSC2016」时空旅行
目录 @description@ @solution@ @accepted code@ @details@ @description@ 2045 年,人类的技术突飞猛进,已经找到了进行时空旅行的方法. ...
- 【CTSC2016】时空旅行
链接 http://uoj.ac/problem/198 题解 首先要发现答案要我们求这个式子: \[ ans=min\bigl((x_i-x)^2+c_i\bigr) \] 显而易见的是这种时空嫁接 ...
- [UOJ198]时空旅行
看懂题目就知道$y,z$是没用的,这题相当于是给一堆$(x_i,c_i)$和询问$x_q$,要求$(x_q-x_i)^2+c_i$的最大值 先把这个式子拆开:$-2x_ix_q+x_i^2+c_i+x ...
- 【UOJ #198】【CTSC 2016】时空旅行
http://uoj.ac/problem/198 (先补一下以前的题解) 这道题5分暴力好写好调,链上部分分可以用可持久化线段树,每次旅行\(x\)值相同的可以用标记永久化线段树.我还听到某些神犇说 ...
随机推荐
- table调整td宽度整理-完美解决--费元星前端
个人整理例子,留下做个备份 最终重要的几句话 0.日期格式 format="ognl:dateFormat" <td align="center"> ...
- centos7下安装oracle11gR2的详细步骤
环境准备 安装包: CentOS-7-x86_64-DVD linux.x64_11gR2_database_1of2.zip linux.x64_11gR2_database_2of2.zip 本教 ...
- Word中使用宏调整表格
Dim i As Integer For i = 1 To Selection.Tables.Count Selection.Tables(i).Columns(9).Delete Selecti ...
- facebook hash key
private void printHashKey() { try { PackageInfo info = getPackageManager().getPackageInfo( "xxx ...
- IDA动态调试SO文件
1. 所需工具 IDA Pro 6.6. 安卓SDK工具 2. 模拟器设置 将ida所在目录的dbgsrv文件夹内的android_server文件push到模拟器中. 设置777属性 启动调试服务器 ...
- Qt 解析网络数据出现ssl错误
最近写了点小东西,哈哈, 网络部分是同学帮我搞的 在编译的时候,出现了一下错误 qt.network.ssl: QSslSocket: cannot call unresolved function ...
- 虚拟现实-VR-UE4-编译UE4源码
通过Git将UE4源代码获取到本地计算机 切记路径不要有中文 这里面我已经在进行编译了,有部分文件是多余出来的, 第一步就是点击 setup.bat批处理,这个过程回取决与你的网速的快慢,我等了一下午 ...
- (转)简述47种Shader Map的渲染原理与制作方法
在Shader中会使用各种不同图参与渲染,所以简单地总结下各种图的渲染原理.制作方法,最后面几种是程序生成图. 1. Albedo 2. Diffuse(Photographic) 从上图可以看出来, ...
- 基于Ubuntu搭建Linux路由器
开源,几乎代表了无所不能的意思,最近又因为它玩Hi了... 因业务发展,需要临时接入300MB的专线和千兆路由器,而公司现有的路由器却是百兆的,出于成本考虑,只能不想更换新的路由器,在网上查了一下可以 ...
- WebSocket 与 HTTP/2
个人笔记 WebSocket WebSocket 是一个双向通信协议,它在握手阶段采用 HTTP/1.1 协议(暂时不支持 HTTP/2). 握手过程如下: 首先客户端向服务端发起一个特殊的 HTTP ...