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\)值相同的可以用标记永久化线段树.我还听到某些神犇说 ...
随机推荐
- 剖析DI
0x00.前言 当我们研究一些晦涩的源码,上网查阅资料的时候,映入眼帘的总有这么些名词:DIP.IOC.DI.DL.IOC容器这些专业名词.如果不懂这些名词背后的含义,我们内心有可能是这样的: 0x0 ...
- OpenCV入门:(一:安装与配置)
看到的不是自己的,只有写下来的才是自己的,上次接触OpenCV实在三个月前,亢奋的看完了OpenCV自带的入门文档,觉得对图形处理有了一点点了解,现在三个月过去了,由于学习需要,想深入了解OpenCV ...
- 孤荷凌寒自学python第六十八天学习并实践beautifulsoup模块1
孤荷凌寒自学python第六十八天学习并实践beautifulsoup模块1 (完整学习过程屏幕记录视频地址在文末) 感觉用requests获取到网页的html源代码后,更重要的工作其实是分析得到的内 ...
- 基于Ubuntu搭建Linux路由器
开源,几乎代表了无所不能的意思,最近又因为它玩Hi了... 因业务发展,需要临时接入300MB的专线和千兆路由器,而公司现有的路由器却是百兆的,出于成本考虑,只能不想更换新的路由器,在网上查了一下可以 ...
- MySQL统计数据库表大小
use information_schema; SELECT TABLE_NAME, (DATA_LENGTH/1024/1024) as DataM , (INDEX_LENGTH/1024/102 ...
- HDU 4722 Good Numbers(位数DP)(2013 ACM/ICPC Asia Regional Online ―― Warmup2)
Description If we sum up every digit of a number and the result can be exactly divided by 10, we say ...
- Linux yum安装MySQL5.7,及远程连接mysql(亲测有效!)
一.安装配置MySQL的yum源 # 安装MySQL的yum源,下面是RHEL6系列的下载地址 rpm -Uvh http://dev.mysql.com/get/mysql-community-re ...
- 安装floodlight遇到的问题和解决
环境:ubuntu18.04 安装floodlight先前准备:java的环境,ant. sudo apt-get install build-essential defailt-jdk ant py ...
- libevent 多线程
对于evbuffer,如果libevent使用了evthread_use_pthreads();那么所有的单个evbuffer操作就已经是原子的了,调用操作相关的接口进去就上锁,出来解锁,那么 evb ...
- JMS实战——ActiveMQ实现Pub-Sub
前言 上篇博客<JMS实战--ActiveMQ>介绍了ActiveMQ的安装,并实现了简单的PTP模型.这篇博客我们来看一下Pub-Sub模型,之后来总结一下JMS. 实现 项目结构 其中 ...