uoj

description

你要维护若干个集合,每个集合都是有一个编号比他小的集合扩展而来,扩展内容为加入一个新的元素\((x,c)\)或者删除一个已有元素。集合的扩展关系之间构成一个树形结构。
有\(m\)次询问,每次给出一个\(x_0\),询问第\(s\)个集合中\((x-x_0)^2+c\)的最小值。
\(n,m\le5\times10^5\)

sol

把这个树形结构建出来,然后一个元素在树上存在的位置就是——一个连通块?
这样转化显得很蠢,实际上一个元素在树上存在的位置就是它第一次出现的点的子树中扣掉把它删除的点的子树。
这样子\(n\)种元素在树上的存在位置就是\(n\)个在\(\mbox{dfs}\)序上的连续区间。
观察答案式,因为长得很斜率优化,所以就把这\(n\)个区间丢到线段树上,在线段树的每个节点维护一个下凸壳。每个询问就在线段树的一条链上的每个线段树节点里边的凸壳上二分。复杂度\(O(n\log^2n)\)。
发现每次二分很蠢,可以直接在外部对询问的\(x\)排序,然后就不需要二分了。复杂度\(O(n\log n)\)。

code

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
#define ll long long
ll gi(){ll x=0,w=1;char ch=getchar();while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar();if (ch=='-') w=0,ch=getchar();while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return w?x:-x;
}
const int N = 5e5+5;
struct point{ll x,y;}p[N];
struct node{int x,s,id;bool operator < (const node &b) const{return x<b.x;}
}q[N];
vector<int>S[N];vector<int>v[N<<2];
int n,m,nxt[N],head[N],val[N],dfn[N],low[N],tim,id[N],hd[N<<2];
ll X[N],C[N],ans[N];
void dfs(int u){dfn[u]=++tim;S[val[u]].push_back(u);for (int v=head[u];v;v=nxt[v]) dfs(v);low[u]=tim;
}
bool cmp(int i,int j){return X[i]==X[j]?C[i]>C[j]:X[i]<X[j];}
void modify(int x,int l,int r,int ql,int qr,int i){if (l>=ql&&r<=qr){int sz=v[x].size();while(sz>1&&(p[v[x][sz-1]].y-p[v[x][sz-2]].y)*(p[i].x-p[v[x][sz-1]].x)>=(p[i].y-p[v[x][sz-1]].y)*(p[v[x][sz-1]].x-p[v[x][sz-2]].x))--sz,v[x].pop_back();v[x].push_back(i);return;}int mid=l+r>>1;if (ql<=mid) modify(x<<1,l,mid,ql,qr,i);if (qr>mid) modify(x<<1|1,mid+1,r,ql,qr,i);
}
ll query(int x,int l,int r,int s,int k){ll res=1ll<<60;if (int sz=v[x].size()){while (hd[x]<sz-1&&p[v[x][hd[x]+1]].y-p[v[x][hd[x]]].y<1ll*k*(p[v[x][hd[x]+1]].x-p[v[x][hd[x]]].x)) ++hd[x];res=p[v[x][hd[x]]].y-p[v[x][hd[x]]].x*k+1ll*k*k;}if (l==r) return res;int mid=l+r>>1;if (s<=mid) return min(res,query(x<<1,l,mid,s,k));else return min(res,query(x<<1|1,mid+1,r,s,k));
}
int main(){n=gi();m=gi();C[1]=gi();val[1]=1;for (int i=2;i<=n;++i)if (!gi()){int f=gi()+1,id=gi()+1;X[id]=gi();gi(),gi();C[id]=gi();nxt[i]=head[f];head[f]=i;val[i]=id;}else{int f=gi()+1,id=gi()+1;nxt[i]=head[f];head[f]=i;val[i]=id;}dfs(1);for (int i=1;i<=n;++i) id[i]=i;sort(id+1,id+n+1,cmp);for (int i=1;i<=n;++i)if (S[id[i]].size()){p[i]=(point){2ll*X[id[i]],X[id[i]]*X[id[i]]+C[id[i]]};int lst=dfn[S[id[i]][0]];for (int j=1,sz=S[id[i]].size();j<sz;++j){if (lst<dfn[S[id[i]][j]]) modify(1,1,n,lst,dfn[S[id[i]][j]]-1,i);lst=low[S[id[i]][j]]+1;}if (lst<=low[S[id[i]][0]]) modify(1,1,n,lst,low[S[id[i]][0]],i);}for (int i=1,s,x;i<=m;++i) s=gi()+1,x=gi(),q[i]=(node){x,dfn[s],i};sort(q+1,q+m+1);for (int i=1;i<=m;++i) ans[q[i].id]=query(1,1,n,q[i].s,q[i].x);for (int i=1;i<=m;++i) printf("%lld\n",ans[i]);return 0;
}

转载于:https://www.cnblogs.com/zhoushuyu/p/9385906.html

[UOJ198][CTSC2016]时空旅行相关推荐

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

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

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

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

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

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

  4. [CTSC2016]时空旅行

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

  5. 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+ ...

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

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

  7. CTSC2016时空旅行

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

  8. Luogu P5416 [CTSC2016]时空旅行

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

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

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

最新文章

  1. 新兴内存技术准备突围
  2. 就是个控制结构,Scala 能有什么新花样呢?
  3. GBRT(GBDT)(MART)(Tree Net)(Tree link)
  4. [USACO1.3]滑雪课程设计Ski Course Design
  5. 07-图4 哈利·波特的考试 (25 分)
  6. JDK源码解析之java.util.Iterator和java.lang.Iterable
  7. Span中显示内容过长显示省略号---SpringCloud Alibaba_若依微服务框架改造_前端基于Vue的ElementUI---工作笔记011
  8. select下拉框带模糊查询_SQL 之 简单查询
  9. linux wc -l命令,Linux wc sort和uniq的用法
  10. RDMA 、InfiniBand、IB卡、IB驱动 之间的关系!
  11. 描写计算机教室的词语,形容教室环境布置的句子
  12. Vuex--mapState, mapGetters, mapActions, mapMutations--使用/教程/实例
  13. java使用itextpdf生成PDF批量打印荣誉证书(指定位置输出文字)
  14. SQL 2008 -数据库的创建与管理
  15. 500以内什么耳机好?盘点500元蓝牙耳机性价比之王
  16. 51单片机实战教程之C语言基础(五 C语言函数及其定义)
  17. 【养生】【作息】作息+十二时辰养生
  18. 利用wine使用msoffice软件
  19. Matlab如何调整坐标轴刻度
  20. 3分钟短文:Laravel的“南天门”,过滤掉七七八八的数据

热门文章

  1. ubuntu 下最简单的歌词软件osdlyric (with banshee)
  2. 微信公众号采集,历史文章采集,万能key采集,点赞阅读评论采集
  3. 新浪微博模拟登录分析(含验证码)
  4. php音频对比技术,HIFIDIY论坛-三种音频功放的音质特点比较 供参考 - Powered by Discuz!...
  5. python爬取微博评论点赞数_python 爬虫 爬微博 分析 数据
  6. 如何搭建企业数据化运营体系?
  7. 八股文之linux常用指令
  8. ALLEGRO-DRC-错误代码
  9. 同一个页面显示多个html界面,浏览器怎么设置在同一个界面/窗口打开多个网页...
  10. 100本《架构师》迷你书——限时免费领取