CTSC2016时空旅行
当时看这道题AC的人数比较多,就开了这道题。
很容易发现是这是一个有关凸包的题。
然后不知道怎么维护凸包,一直在想cdq,感觉复杂度不行,于是被这玩意难住了……
幸好有亲学长yyh造福人类的题解:https://blog.csdn.net/qwsin/article/details/70884985,十分详细,而且相对容易看懂些,脑回路跟我差不多。
发现主要是我没学线段树标记永久化,所以去学了一下这个东西:https://www.cnblogs.com/Hallmeow/p/8004676.html
大概就是,为了懒得pushdown,就做一个标记,每次询问的时候,拿到这个标记,就直接更新答案……
应用到这道题上,我们发现所有询问都是单点询问,就是说会每次都会走到线段树的最底层。
这样就有个好处:我们往线段树的一段区间的凸包加一个点时,只有走到线段树上被区间完全包含的点的时候,在这里的凸包上加点,然后return
中途没被修改区间完全覆盖的线段树上的地方,就不用在凸包上加点。
然后这道题的主要特点是,用了很多排序,让凸包的优秀性质,最大得发挥。
具体参考学长yyh的题解
bz上又卡常,我是真的卡不过去,yyh的代码也要T……
//Serene
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<vector>
using namespace std;
#define ll long long
#define db double
#define For(i,a,b) for(int i=(a);i<=(b);++i)
#define Rep(i,a,b) for(int i=(a);i>=(b);--i)
const int maxn=5e5+7;
const ll INF=1e18+7;
ll n,m,c0,ans[maxn];//don't forget the earth char cc; ll ff;
template<typename T>void read(T& aa) {
aa=0;cc=getchar();ff=1;
while((cc<'0'||cc>'9')&&cc!='-') cc=getchar();
if(cc=='-') ff=-1,cc=getchar();
while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
aa*=ff;
} int fir[maxn],nxt[maxn],to[maxn],e=0;
void add(int x,int y) {
// printf("add:%d->%d\n",x,y);
to[++e]=y;nxt[e]=fir[x];fir[x]=e;
} int dfn[maxn],end[maxn],dfn_clock=-1;
void dfs(int pos) {
dfn[pos]=++dfn_clock;
for(int y=fir[pos];y;y=nxt[y]) dfs(to[y]);
end[pos]=dfn_clock;
} struct Plt{
ll id,x,y,pos;
Plt(){}
Plt(ll id,ll x,ll y,ll pos):id(id),x(x),y(y),pos(pos){}
bool operator < (const Plt& b) const{return x==b.x? y>b.y:x<b.x;}
}plt[maxn];
vector<int>del[maxn];
bool cmp(const int a,const int b) {return dfn[a]<dfn[b];}
int totp; struct Ask{
ll qid,pos,k,x;
Ask(){}
Ask(ll qid,ll pos,ll k,ll x):qid(qid),pos(pos),k(k),x(x){}
bool operator < (const Ask& b) const{return k>b.k;}
}ask[maxn]; struct Node{
ll x,y;
Node(){}
Node(ll x,ll y):x(x),y(y){}
}o,D; struct Seg{
int p;//current pos on convex hull
vector<Node> G;
Seg(){G.clear();p=0;}
void push(Node x) {G.push_back(x);}
void pop() {G.pop_back();}
}seg[4*maxn];
ll ql,qr,qa,qb; ll get_ans(ll k,ll b,Node s) {return k*s.x+s.y+b;} void get_push(int pos) {
ll X1,Y1,X2,Y2,r=seg[pos].G.size();
while(r&&seg[pos].G[r-1].x==o.x) seg[pos].pop(),r--;
while(r>=2) {
X1=seg[pos].G[r-1].x-seg[pos].G[r-2].x;
Y1=seg[pos].G[r-1].y-seg[pos].G[r-2].y;
X2=o.x-seg[pos].G[r-2].x;
Y2=o.y-seg[pos].G[r-2].y;
if((db)Y1/X1<(db)Y2/X2) break;
seg[pos].pop(); r--;
}
seg[pos].push(o);
} void chge(int pos,int l,int r) {
if(l>=ql&&r<=qr) {
get_push(pos);
return;
}
int mid=(l+r)>>1;
if(ql<=mid) chge(pos<<1,l,mid);
if(qr>mid) chge(pos<<1|1,mid+1,r);
} void get_insert(int i) {
int x=plt[i].id,ld=dfn[plt[i].pos],rd=end[plt[i].pos];
o=Node(plt[i].x,plt[i].y);
sort(del[x].begin(),del[x].end(),cmp);
int N=del[x].size()-1;
For(i,0,N) {
if(ld<dfn[del[x][i]]) {
ql=ld; qr=min(rd,dfn[del[x][i]]-1);
chge(1,1,n);
}
ld=max(ld,end[del[x][i]]+1);
if(ld>rd) break;
}
if(ld<=rd) {ql=ld; qr=rd; chge(1,1,n);}
} #define np seg[pos].p ll ud_ans(int pos) {
if(!seg[pos].G.size()) return INF;
ll rs=get_ans(qa,qb,seg[pos].G[np]),now,N=seg[pos].G.size();
while(np+1<N) {
now=get_ans(qa,qb,seg[pos].G[np+1]);
if(now>=rs) break;
rs=now; np++;
}
return rs;
} ll q(int pos,int l,int r) {
ll rs=ud_ans(pos);
if(l==r) return rs;
int mid=(l+r)>>1;
if(ql<=mid) rs=min(rs,q(pos<<1,l,mid));
if(qr>mid) rs=min(rs,q(pos<<1|1,mid+1,r));
return rs;
} int main() {
read(n); read(m); read(c0);
D=Node(0,c0);
ll op,id,x,y,z,c,f;
For(i,1,n-1) {
read(op); read(f); read(id); add(f,i);
if(!op) {
read(x); read(y); read(z); read(c);
plt[++totp]=Plt(id,x,x*x+c,i);
}
else del[id].push_back(i);
}
dfs(0);
sort(plt+1,plt+totp+1);
For(i,1,totp) get_insert(i);
For(i,1,m) {
read(id); read(x);
ask[i]=Ask(i,dfn[id],-2*x,x*x);
ans[i]=get_ans(-2*x,x*x,D);
}
sort(ask+1,ask+m+1);
For(i,1,m) {
ql=qr=ask[i].pos; qa=ask[i].k; qb=ask[i].x;
if(ql) ans[ask[i].qid]=min(ans[ask[i].qid],q(1,1,n));
}
For(i,1,m) printf("%lld\n",ans[i]);
return 0;
}
CTSC2016时空旅行的更多相关文章
- Luogu P5416 [CTSC2016]时空旅行
第一次写线段树分治的题目,没想到是道这么毒的题233 首先发现题目里的\((x,y,z,c)\)就是在放屁,只有\((x,c)\)是有用的 因此我们可以把题意转化为,在某一个时间节点上,求出所有元素的 ...
- [UOJ198][CTSC2016]时空旅行
uoj description 你要维护若干个集合,每个集合都是有一个编号比他小的集合扩展而来,扩展内容为加入一个新的元素\((x,c)\)或者删除一个已有元素.集合的扩展关系之间构成一个树形结构. ...
- [CTSC2016]时空旅行
description 题面 solution 线段树分治+斜率优化毒瘤题 题目可以简化为: 你要维护一个包含元素\((x,c)\)的集合 修改操作为从以前的一个版本更新,修改内容为添加或删除一个元素 ...
- [CTSC2016]时空旅行(线段树+凸包)
应该是比较套路的,但是要A掉仍然不容易. 下面理一下思路,思路清楚了也就不难写出来了. 0.显然y,z坐标是搞笑的,忽略即可. 1.如果x不变,那么直接set即可解决. 2.考虑一个空间和询问x0,通 ...
- @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【CTSC2016】时空旅行
传送门:http://uoj.ac/problem/198 [题解] 首先y.z是没有用的.. 然后式子就是w = (x0-xi)^2+ci的最小值,化出来可以变成一个直线的形式. 然后我们可以用线段 ...
- 【UOJ #198】【CTSC 2016】时空旅行
http://uoj.ac/problem/198 (先补一下以前的题解) 这道题5分暴力好写好调,链上部分分可以用可持久化线段树,每次旅行\(x\)值相同的可以用标记永久化线段树.我还听到某些神犇说 ...
- [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 ...
随机推荐
- Spring MVC(十二)--使用ModelView实现重定向
上一篇总结了使用返回字符串的方式实现重定向以及重定向过程中传递字符串参数和pojo参数的过程,本篇总结另一种重定向的实现方式--返回ModelAndView 这次的场景是这样的:在页面输入一些信息添加 ...
- 15_K-近邻算法之入住位置预测
案例:本次大赛的目的是预测一个人想签入到哪个地方.对于本次比赛的目的,Facebook的创建一 个人造的世界,包括位于10公里的10平方公里超过10万米的地方.对于一个给定的坐标,你的任务是返回最有可 ...
- python3-常用模块之openpyxl(1)
1.创建工作簿 from openpyxl import Workbook # 创建excel对象 wb = Workbook() # 获取第一个sheet = wb.active # 单元格写入内容 ...
- python collections模块 之 orderdict
普通字典善于隐射,其次追踪插入顺序.而 orderdict 更善于后者.因为 orderdict 内部维护了一个双向链表,大小会是普通字典的两倍. 增加方法: popitem(last=True) 移 ...
- PKU--1267 Cash Machine(多重背包)
题目http://poj.org/problem?id=1276 分析 这是一个多重背包的问题,可以把请求的金额当作背包的重量,而货币的面值就是价值又是重量. 于是这个问题便很好理解背包了. #];; ...
- 转载https://www.luogu.org/problemnew/solution/P1665,http://bailian.openjudge.cn/practice/2002/的新解法
不知道为什么O(n^4)O(n4)的玄学方法能过,正解显然是O(n^2)O(n2)的,枚举对角线,然后算出另外两点判断存不存在. 关键就在怎么通过对角线算出另外两点的坐标. 先贴公式. int mid ...
- Leetcode961. N-Repeated Element in Size 2N Array重复N次的元素
在大小为 2N 的数组 A 中有 N+1 个不同的元素,其中有一个元素重复了 N 次. 返回重复了 N 次的那个元素. 示例 1: 输入:[1,2,3,3] 输出:3 示例 2: 输入:[2,1,2, ...
- 浪潮云+/云加 App 智能化的企业移动办公平台官网下载地址
上Google?Facebook? 点这里: 手机端:https://ecm.inspur.com/ 桌面端:https://ecm.inspuronline.com/
- C#(.net)中的DllImport
大家在实际工作学习C#的时候,可能会问:为什么我们要为一些已经存在的功能(比如Windows中的一些功能,C++中已经编写好的一些方法)要重新编写代码,C#有没有方法可以直接都用这些原本已经存在的功能 ...
- Python中的sort()
Python中的sort()方法用于数组排序,本文以实例形式对此加以详细说明: 一.基本形式列表有自己的sort方法,其对列表进行原址排序,既然是原址排序,那显然元组不可能拥有这种方法,因为元组是不可 ...