[THUPC2019]不等式/[51Nod1598]方程最小值

题目大意:

给定\(a_{1\sim n}\)和\(b_{1\sim n}\),令\(f_k(x)=\sum_{i=1}^k|a_ix+b_i|\)。对于所有\(k=1\sim n\),求\(f_k\)在\(\mathbb{R}\)中的最小值。

\(1\le n\le 5\times10^5,|a_i|,|b_i|<10^5\)

思路:

\[\sum_{i=1}^k|a_ix+b_i|=\sum_{i=1}^k|a_i||x+\frac{b_i}{a_i}|
\]

画在数轴上就是在\(-\frac{b_i}{a_i}\)(即零点)的位置有\(|a_i|\)个点。要找到一个位置\(x\),使得\(x\)到所有点的距离之和最小。

根据小学奥数的那套理论,\(x\)就是所有零点的加权中位数。我们可以用一个大根堆、一个小根堆来维护所有的零点,并求出中位数。

考虑函数加上绝对值后,\(a_i\)实际的符号。对于\(-\frac{b_i}{a_i}<x\)的函数来说,\(a_i>0\);反之\(a_i<0\)。因此我们可以在对两个堆中的元素分别维护考虑绝对值后\(a_i,b_i\)之和。即可求出最终\(f_k(x)\)的最小值。

时间复杂度\(\mathcal O(n\log n)\)。

源代码:

#include<queue>
#include<cstdio>
#include<cctype>
#include<cassert>
#include<algorithm>
inline int getint() {
register char ch;
register bool neg=false;
while(!isdigit(ch=getchar())) neg|=ch=='-';
register int x=ch^'0';
while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
return neg?-x:x;
}
const int N=5e5+1;
using int64=long long;
using Node=std::pair<double,int>;
std::priority_queue<Node,std::vector<Node>,std::greater<Node>> q1;//small
std::priority_queue<Node,std::vector<Node>,std::less<Node>> q2;//big
int64 s1,s2,a1,a2,b1,b2,a[N],b[N];
double o[N];
int main() {
const int n=getint();
for(register int i=1;i<=n;i++) a[i]=getint();
for(register int i=1;i<=n;i++) b[i]=getint();
for(register int i=1;i<=n;i++) {
if(a[i]!=0) {
o[i]=-1.*b[i]/a[i];
if(s1&&o[i]>q1.top().first) {
q1.push(std::make_pair(o[i],i));
if(a[i]>0) a[i]=-a[i],b[i]=-b[i];
a1+=a[i]; b1+=b[i];
s1+=std::abs(a[i]);
} else {
q2.push(std::make_pair(o[i],i));
if(a[i]<0) a[i]=-a[i],b[i]=-b[i];
a2+=a[i]; b2+=b[i];
s2+=std::abs(a[i]);
}
} else {
b1+=std::abs(b[i]);
}
while(s1>s2) {
q2.push(q1.top());
const int i=q1.top().second;
a1-=a[i]; b1-=b[i];
s1-=std::abs(a[i]);
a[i]=-a[i]; b[i]=-b[i];
a2+=a[i]; b2+=b[i];
s2+=std::abs(a[i]);
q1.pop();
}
while(s2>s1) {
q1.push(q2.top());
const int i=q2.top().second;
a2-=a[i]; b2-=b[i];
s2-=std::abs(a[i]);
a[i]=-a[i]; b[i]=-b[i];
a1+=a[i]; b1+=b[i];
s1+=std::abs(a[i]);
q2.pop();
}
const double x=s1?q1.top().first:0;
printf("%.7f\n",a1*x+b1+a2*x+b2);
}
return 0;
}

[THUPC2019]不等式/[51Nod1598]方程最小值的更多相关文章

  1. C语言作业3

    一.实验目的与要求 1.用for语句实现循环 (1)求数列前n项和 掌握for语句实现循环的方法 (2)求数列前n项和 掌握for语句实现循环的方法 循环嵌套的使用 2.用while循环语句实现循环 ...

  2. HDU 6070 Dirt Ratio(分数规划+线段树)

    http://acm.hdu.edu.cn/showproblem.php?pid=6070 题意: 找出一个区间,使得(区间内不同数的个数/区间长度)的值最小,并输出该值. 思路: 因为是要求$\f ...

  3. 深入理解SVM,软间隔与对偶问题

    今天是机器学习专题的第33篇文章,我们继续来聊聊SVM模型. 在上一篇文章当中我们推到了SVM模型在线性可分的问题中的公式推导,我们最后得到的结论是一个带有不等式的二次项: \[\left\{\beg ...

  4. dp优化-四边形不等式(模板题:合并石子)

    学习博客:https://blog.csdn.net/noiau/article/details/72514812 看了好久,这里整理一下证明 方程形式:dp(i,j)=min(dp(i,k)+dp( ...

  5. 【转】斜率优化DP和四边形不等式优化DP整理

    (自己的理解:首先考虑单调队列,不行时考虑斜率,再不行就考虑不等式什么的东西) 当dp的状态转移方程dp[i]的状态i需要从前面(0~i-1)个状态找出最优子决策做转移时 我们常常需要双重循环 (一重 ...

  6. 省选算法学习-dp优化-四边形不等式

    嗯......四边形不等式的确长得像个四边形[雾] 我们在dp中,经常见到这样一类状态以及转移方程: 设$dp\left[i\right]\left[j\right]$表示闭区间$\left[i,j\ ...

  7. HDU3480 Division——四边形不等式或斜率优化

    题目大意 将N个数分成M部分,使每部分的最大值与最小值平方差的和最小. 思路 首先肯定要将数列排序,每部分一定是取连续的一段,于是就有了方程 $\Large f(i,j)=min(f(i-1,k-1) ...

  8. [学习笔记]四边形不等式优化DP

    形如$f[i][j]=min{f[i][k]+f[k+1][j]}+w[i][j]$的方程中, $w[\;][\;]$如果同时满足: ①四边形不等式:$w[a][c]+w[b][d]\;\leq\;w ...

  9. [家里蹲大学数学杂志]第033期稳态可压Navier-Stokes方程弱解的存在性

    1. 方程  考虑 $\bbR^3$ 中有界区域 $\Omega$ 上如下的稳态流动: $$\bee\label{eq} \left\{\ba{ll} \Div(\varrho\bbu)=0,\\ \ ...

随机推荐

  1. kibana内存设置

    kibana是一个基于NodeJS的单页web应用.而NodeJS则是基于Chrome V8引擎的.V8引擎对于内存的使用是有限制的,默认情况下,64位系统下约为1.4GB,32位系统下约为0.7GB ...

  2. @PropertySouce注解 读取 properties文件

    https://www.cnblogs.com/whx7762/p/7885735.html 1.@ProtertySource @PropertySouce是spring3.1开始引入的基于java ...

  3. 学习docker 部署nginx记录

    docker pull nginx $ docker pull nginx $ docker run --name nginx-test -p 8081:80 -d nginx docker conf ...

  4. java之mybatis整合spring

    这篇讲解spring+mybatis的整合. 目录结构: 一. 整合spring的第一种方法 1. 新建 java 项目 : spring_mybatis 2.导入jar 包-----spring和m ...

  5. Java 之 Session

    Session 一.概述 Session技术:服务器端会话技术,在一次会话的多次请求间共享数据,将数据保存在服务器端的对象(HttpSession)中. 二.使用步骤 1.获取 HttpSession ...

  6. Oracle 11g 体系结构概述

    一.Oracle 体系结构主要用来分析数据库的组成.工作过程与原理,以及数据在数据库中的组织与管理机制. Oracle 数据库是一个逻辑概念,而不是物理概念上安装了 Oracle 数据库管理系统的服务 ...

  7. EXPORT_SYMBOL

    EXPORT_SYMBOL只出现在2.6内核中,在2.4内核默认的非static函数和变量都会自动导入到kernel 空间 作用 EXPORT_SYMBOL标签内定义的函数或者符号对全部内核代码公开, ...

  8. idea上maven打包

    首先要实现maven打包,pom需要引入依赖 pom.xml <project> <dependencies> …… </dependencies> <bui ...

  9. Centos7搭建DockerRegistry

    1. 说明 以下使用系统centos7,64位,镜像为CentOS-7-x86_64-Minimal-1804,均已root用户进行操作 2. 安装Registry Docker Registry 是 ...

  10. Linux 各系统目录作用及内容