题意

一列\(n\)个点,给定一个特殊的图,有两种边\(E(1,i)\)和\(E(i-1,i)\),多个询问,每次给一个\(d\),求所有路径长度加上\(d\)后1到\(n\)的最短路。

分析

  • 首先这图很特殊,大胆猜测不是图论。
  • 1到\(n\)的最短路包括\(p_i\),即1直接到\(i\)的距离,\(i\)作为中转点,加上\(dis_{i,n}\),即\(i\)一直往后走到\(n\)的距离,而该路径的边数就是\(1+n-i\),因此对于每个询问\(d\),该路径的长度就是\(p_i+dis_{i,n}+d*(1+n-i)\)。
  • 因此转化为另一个问题,有\(n\)个二元组\((a_i,b_i)\),对于每个\(d\),求\(min _{i=1}^{n}(a_i+d*b_i)\)。
  • 观察这个二元组的形式,可以再转化为一个几何问题,有\(n\)条直线,斜率为\(b_i\),截距为\(a_i\),对于每个询问的横坐标\(d\),求最小的\(y\)值。
  • 画个图观察,可以知道,我们所需要的就是这些直线下部的折线所围成的一个上凸包。
  • 考虑用单调栈来维护,首先对直线按截距排序,枚举直线,如果斜率比上一条直线大,直接跳过,因为这条直线肯定在凸包的外部,没有贡献。
  • 单调栈维护要考虑栈顶元素什么情况下要去掉,假设当前直线为\(c\),栈顶直线为\(b\),栈顶下一个直线为\(a\),画图可以看出,当\(c\)和\(b\)的交点横坐标小于\(b\)和\(a\)的交点横坐标时,直线\(b\)就是无效的,处于凸包外部,因此出栈。
  • 维护完单调栈后,对询问\(d\)进行排序,显然对于小的\(d\),能使其最优的直线,对于大的\(d\)应该也是优的,且可以继续往下找可以更优的直线,因此只要从小到大排序后扫一遍单调栈即可。

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+50;
const double eps=1e-8;
int t,n,que;
ll p[N],dis[N];
struct Line{
ll k,b;
bool operator <(const Line& rhs)const{
return b<rhs.b;
}
}ls[N],q[N*2];
int sgn(double x){
if(fabs(x)<eps){
return 0;
}
if(x<0){
return -1;
}else{
return 1;
}
}
struct Q{
int id,d;
ll ans;
bool operator <(const Q &rhs)const{
return d<rhs.d;
}
}qs[N];
bool cmp(Q a,Q b){
return a.id<b.id;
}
//两线交点横坐标
double xp(Line a,Line b){
return (b.b-a.b)*1.0/(a.k-b.k);
}
int main(){
// freopen("in.txt","r",stdin);
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&que);
p[1]=0;
for(int i=2;i<=n;i++){
scanf("%lld",&p[i]);
}
dis[1]=p[2];
for(int i=2;i<n;i++){
scanf("%lld",&dis[i]);
}
dis[n]=0;
for(int i=n-1;i>=1;i--){
dis[i]+=dis[i+1];
}
for(int i=1;i<=que;i++){
scanf("%d",&qs[i].d);
qs[i].id=i;
qs[i].ans=0;
}
//构造出n条直线并按截距排序
ls[1]={n-1,p[1]+dis[1]};
for(int i=2;i<=n;i++){
ls[i]={1+n-i,p[i]+dis[i]};
}
sort(ls+1,ls+n);
//维护一个斜率递增的单调队列
int l=1,r=0;
q[r++]=ls[2];
for(int i=3;i<=n;i++){
if(ls[i].k>ls[i-1].k){
//斜率截距都比上一个大,凸包外部
continue;
}
while(r-l+1>=2 && sgn(xp(ls[i],q[r-1])-xp(q[r-1],q[r-2])<=0)){
r--;
}
q[r++]=ls[i];
}
sort(qs+1,qs+1+que);
//越大的增值d乘越大的斜率更优,扫一遍,上一个(小d)能乘的斜率,这一个(大d)肯定也优,但可以更优
int j=0;
for(int i=1;i<=que;i++){
while(j<r-1 && qs[i].d*q[j].k+q[j].b>qs[i].d*q[j+1].k+q[j+1].b){
j++;
}
qs[i].ans=qs[i].d*q[j].k+q[j].b;
}
sort(qs+1,qs+1+que,cmp);
for(int i=1;i<=que;i++){
printf("%lld%c",qs[i].ans,i==que?'\n':' ');
}
}
return 0;
}

2018icpc宁夏邀请赛网络赛_G_Trouble of Tyrant的更多相关文章

  1. 南昌邀请赛网络赛 D.Match Stick Game(dp)

    南昌邀请赛网络赛 D.Match Stick Game 题目传送门 题目就会给你一个长度为n的字符串,其中\(1<n<100\).这个字符串是一个表达式,只有加减运算符,然后输入的每一个字 ...

  2. 2018宁夏邀请赛网赛 I. Reversion Count(java练习题)

    题目链接 :https://nanti.jisuanke.com/t/26217 Description: There is a positive integer X, X's reversion c ...

  3. POJ-2796 & 2019南昌邀请赛网络赛 I. 区间最大min*sum

    http://poj.org/problem?id=2796 https://nanti.jisuanke.com/t/38228 背景 给定一个序列,对于任意区间,min表示区间中最小的数,sum表 ...

  4. 2019 ICPC南昌邀请赛网络赛比赛过程及题解

    解题过程 中午吃饭比较晚,到机房lfw开始发各队的账号密码,byf开始读D题,shl电脑卡的要死,启动中...然后听到谁说A题过了好多,然后shl让blf读A题,A题blf一下就A了.然后lfw读完M ...

  5. icpc 南昌邀请赛网络赛 Max answer

    就是求区间和与区间最小值的积的最大值 但是a[i]可能是负的 这就很坑 赛后看了好多dalao的博客 终于a了 这个问题我感觉可以分为两个步骤 第一步是对于每个元素 以它为最小值的最大区间是什么 第二 ...

  6. icpc 南昌邀请赛网络赛 Subsequence

    题目链接:https://nanti.jisuanke.com/t/38232 就是判断输入是不是子序列 没想到贡献了将近十几次罚时..........可以说是菜的真实了 用cin cout超时了 改 ...

  7. Minieye杯第十五届华中科技大学程序设计邀请赛网络赛D Grid(简单构造)

    链接:https://ac.nowcoder.com/acm/contest/560/D来源:牛客网 题目描述 Give you a rectangular gird which is h cells ...

  8. 2019 ICPC南昌邀请赛 网络赛 K. MORE XOR

    说明 \(\oplus x​\)为累异或 $ x^{\oplus(a)}​$为异或幂 题意&解法 题库链接 $ f(l,r)=\oplus_{i=l}^{r} a[i]$ $ g(l,r)=\ ...

  9. Minieye杯第十五届华中科技大学程序设计邀请赛网络赛 部分题目

    链接:https://pan.baidu.com/s/12gSzPHEgSNbT5Dl2QqDNpA 提取码:fw39 复制这段内容后打开百度网盘手机App,操作更方便哦 D    Grid #inc ...

随机推荐

  1. CF1213F Unstable String Sort

    题目链接 问题分析 题目实际上是一堆大于等于的约束.观察这\(2n-2\)个约束.第一组可以将要求的排成一个不降的序列,然后第二组就是在第一组的基础上再添加条件. 不妨设第一组生成的不降序列是\(\{ ...

  2. 2002: [Hnoi2010]Bounce 弹飞绵羊(分块)

    2002: [Hnoi2010]Bounce 弹飞绵羊 时间限制: 10 Sec  内存限制: 259 MB 题目描述 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他 ...

  3. js几种加密方法

    1.base64加密 它的github地址:https://github.com/dankogai/js-base64 <!DOCTYPE HTML> <html> <h ...

  4. R_Studio(聚类)针对iris数据比较几种聚类方法优劣

    聚类分析 百度百科:传送门 聚类分析指将物理或抽象对象的集合分组为由类似的对象组成的多个类的分析过程 聚类与分类的不同在于,聚类所要求划分的类是未知的 聚类分析是一种探索性的分析,在分类的过程中,人们 ...

  5. 12.并发编程--Queue

    并发编程--Queue Queue - 非阻塞队列 - 阻塞队列 Queue是一种特殊的线性表,它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作.进行插入操作的端称为 ...

  6. Java并发编程的艺术笔记(六)——HashMap、ConcurentHashMap的原理与实现

    一.线程不安全的HashMap 多线程环境下,使用HashMap进行put操作会引起死循环(jdk1.7 Entry链表形成环形数据结构),导致CPU利用率接近100%. 结构:数组 table[]+ ...

  7. C++入门经典-例6.20-修改string字符串的单个字符

    1:使用+可以将两个string 字符串连接起来.同时,string还支持标准输入输出函数.代码如下: // 6.20.cpp : 定义控制台应用程序的入口点. // #include "s ...

  8. vue组件化初体验 全局组件和局部组件

    vue组件化初体验 全局组件和局部组件 vue组件化 全局组件 局部组件  关于vue入门案例请参阅 https://www.cnblogs.com/singledogpro/p/11938222.h ...

  9. 阶段3 3.SpringMVC·_01.SpringMVC概述及入门案例_07.入门案例中使用的组件介绍

    这里配置上注解的支持,相当于配置了上面的前端控制器.处理映射器这两个

  10. pycharm修改代码后第一次运行不生效解决

    问题: 用pycharm每次修改代码后第一次运行还是原来的结果,运行第二次的时候才是修改后代码的结果 解决: 每次修改代码后保存一下即可解决