P4293 [WC2010]能量场

题意

给你 \(n\) 个粒子,每个粒子有两个权值 \(m_i,c_i\) 每个相邻有序对 \((a,b)\) 会产生 \(m_am_b(c_a-c_b)\) 的贡献。现让你处理两个问题:

  1. 找出一个有序对使贡献最大。
  2. 找出一个序列成环后贡献和最大。

思路

我们将贡献转化一下:

\[m_am_b(c_a-c_b)=m_ac_am_b-m_bc_bm_a
\]

那么这就形成了一个叉积的形式。即将每个点 \(i\) 转化为 \(x=m_ic_i,y=m_i\) 的向量。

那么第一问就等价于求叉积最大的两个向量。具体怎么求后面再说。

那么第二问就是将若干个向量依次首尾相接地叉积和。因为所有点都在第一象限,所以这等价于求一个多边形的面积的两倍。(不会的可以自己根据叉积意义推下)

那么我们让贡献和最大,相当于求一个构成多边形面积最大的序列——凸包。于是我们求一下凸包就行了。

至于第一问,我们要快速得到两个点叉积的最大值,发现叉积最大的两个点一定在凸包上。并且发现,顺次遍历所有点并用一个指针记录另一个点的位置,发现叉积的绝对值是单调的。那么我们用类似半平面交的方法扫两遍凸包就行了,即正反各扫一遍(因为边界条件可能错误,但扫两遍一定会统计完全)。

实现

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cctype>
#include<cstring>
#include<cmath>
using namespace std;
namespace star
{
const int maxn=5e4+10;
int n,m=1,ans,Ans[2],q[maxn];
struct vec{
double x,y;
int id;
vec(double x=0,double y=0,int id=0):x(x),y(y),id(id){}
vec operator + (const vec &a) const {return vec(x+a.x,y+a.y);}
vec operator - (const vec &a) const {return vec(x-a.x,y-a.y);}
double operator * (const vec &a) const {return x*a.y-y*a.x;}
bool operator < (const vec &a) const {return x<a.x or (x==a.x and y<a.y);}
}a[maxn];
inline void work(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
double a,b;
scanf("%lf%lf",&a,&b);
star::a[i]=vec(a*b,a,i);
}
sort(a+1,a+1+n);
q[1]=1;
for(int i=2;i<=n;i++){
while(m>1 and (a[q[m]]-a[q[m-1]])*(a[i]-a[q[m]])<=0) m--;
q[++m]=i;
}
int tmp=m;
for(int i=n-1;i;i--){
while(m>tmp and (a[q[m]]-a[q[m-1]])*(a[i]-a[q[m]])<=0) m--;
q[++m]=i;
}
for(int i=1,j=2;i<=m;i++){
while(fabs(a[q[i]]*a[q[j]])<fabs(a[q[i]]*a[q[j+1]])) j=j%(m-1)+1;
double res=a[q[i]]*a[q[j]];
if(ans<fabs(res)){
ans=fabs(res);
if(res>0)Ans[0]=i,Ans[1]=j;
else Ans[0]=j,Ans[1]=i;
}
}
for(int i=m,j=m-1;i;i--){
while(fabs(a[q[i]]*a[q[j]])<fabs(a[q[i]]*a[q[j==1?m-1:j-1]])) j=j==1?m-1:j-1;
double res=a[q[i]]*a[q[j]];
if(ans<fabs(res)){
ans=fabs(res);
if(res>0)Ans[0]=i,Ans[1]=j;
else Ans[0]=j,Ans[1]=i;
}
}
printf("%d %d\n%d\n",a[q[Ans[0]]].id,a[q[Ans[1]]].id,m-1);
for(int i=1;i<m;i++) printf("%d ",a[q[i]].id);
}
}
signed main(){
star::work();
return 0;
}

补充

洛谷的另外一篇题解在代码在数据较小时进行了特判以水过第一个测试点,实际上如果不加特判其根本无法通过此题,原因很可能就是没有进行反方向统计答案。

P4293 [WC2010]能量场的更多相关文章

  1. BZOJ1758: [Wc2010]重建计划

    题解: 这题我居然做了一星期?... 平均值的极值其实也可以算是一种分数规划,只不过分母上b[i]=1 然后我们就可以二分这个值.类似与 HNOI最小圈 如果没有 链的长度的限制的话,我们直接两遍df ...

  2. 洛谷 P4292 [WC2010]重建计划 解题报告

    P4292 [WC2010]重建计划 题目描述 \(X\)国遭受了地震的重创, 导致全国的交通近乎瘫痪,重建家园的计划迫在眉睫.\(X\)国由\(N\)个城市组成, 重建小组提出,仅需建立\(N-1\ ...

  3. [WC2010]重建计划 长链剖分

    [WC2010]重建计划 LG传送门 又一道长链剖分好题. 这题写点分治的人应该比较多吧,但是我太菜了,只会长链剖分. 如果你还不会长链剖分的基本操作,可以看看我的长链剖分总结. 首先一看求平均值最大 ...

  4. 【BZOJ1758】【WC2010】重建计划(点分治,单调队列)

    [BZOJ1758][WC2010]重建计划(点分治,单调队列) 题面 BZOJ 洛谷 Description Input 第一行包含一个正整数N,表示X国的城市个数. 第二行包含两个正整数L和U,表 ...

  5. 「WC2010」重建计划(长链剖分/点分治)

    「WC2010」重建计划(长链剖分/点分治) 题目描述 有一棵大小为 \(n\) 的树,给定 \(L, R\) ,要求找到一条长度在 \([L, R]\) 的路径,并且路径上边权的平均值最大 \(1 ...

  6. bzoj 1758 [Wc2010]重建计划 分数规划+树分治单调队列check

    [Wc2010]重建计划 Time Limit: 40 Sec  Memory Limit: 162 MBSubmit: 4345  Solved: 1054[Submit][Status][Disc ...

  7. bzoj1758 [Wc2010]重建计划 & bzoj2599 [IOI2011]Race

    两题都是树分治. 1758这题可以二分答案avgvalue,因为avgvalue=Σv(e)/s,因此二分后只需要判断Σv(e)-s*avgvalue是否大于等于0,若大于等于0则调整二分下界,否则调 ...

  8. bzoj 1758: [Wc2010]重建计划

    Description Input 第 一行包含一个正整数N,表示X国的城市个数. 第二行包含两个正整数L和U,表示政策要求的第一期重建方案中修建道路数的上下限 接下来的N-1行描述重建小组的原有方案 ...

  9. BZOJ1758: [Wc2010]重建计划(01分数规划+点分治+单调队列)

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1758 01分数规划,所以我们对每个重心进行二分.于是问题转化为Σw[e]-mid>=0, ...

随机推荐

  1. Qt中的布局浅析与弹簧的使用,以及Qt居中的两种方法

    1. 布局 为什么要布局: 布局之后窗口的排列是有序的 布局之后窗口的大小发生变化, 控件的大小也会对应变化 如果不对控件布局, 窗口显示出来之后有些控件的看不到的 布局是可以嵌套使用 常用的布局方式 ...

  2. CLR里的MethodTable,MethodDescChunk,MethodDesc,FixUpPreCode都是什么意思

    一:看下面一些概念 1MethodTable MethodTable可以说在CLR里面无处不在,这个东西主要是作为对象的数据类型存在,主要包含了EEClass 模块地址,类型名称,模块路径等. 2.E ...

  3. 干货 | LuatOS BSP移植教程,简单到复制粘贴!!!

    LuatOS本着自身的开源特性,可以很轻松的嵌入到很多微处理器和微控制器.今天简要讲下如何移植这套系统,上手比较简单,看完基本就会了. 要想做移植,就要先了解需要移植芯片的SDK,LuatOS依赖于F ...

  4. LCD1602液晶显示模块的单片机驱动深入详解之硬件篇

    (本文以HD44780主控芯片的LCD1602为蓝本进行描述,其中的截图也来自HD44780数据手册,用户可自行搜索其datasheet,有部分整理网上的,但绝对要比你看到的要深入得多) 一.接口 L ...

  5. OSPF多区域原理与配置

    OSPF多区域原理与配置 目录 一.OSPF多区域生成 1.1.生成OSPF多区域的原因 二.OSPF的三种通信量 2.1.域内通信量 2.2.域间通信量 2.3.外部通信量 三.OSPF的路由器类型 ...

  6. 1、JVM体系结构

    1.JVM跨语言的平台 随着java7的正式发布,java虚拟机的设计者们通过JSR-292规范基本实现在java虚拟机平台上运行非java语言编写的程序. java虚拟机根本不关心运行在其内部的程序 ...

  7. kubelet分析-pvc扩容源码分析

    kubernetes ceph-csi分析目录导航 存储的扩容分为controller端操作与node端操作两大步骤,controller端操作由external-resizer来调用ceph完成,而 ...

  8. Kubernetes之无头服务(headless)

    己经看到如何使用服务来提供稳定的ip地址,从而允许客户端连接到支持服务的每个pod (或其他端点).到服务的每个连接都被转发到一个随机选择的pod上.但是如果客户端需要链接到所有的pod呢?如果后端的 ...

  9. 第15章: Prometheus监控Kubernetes资源与应用

    Prometheus监控Kubernetes资源与应用 目录 1 监控方案 2 2 监控指标 4 3 实现思路 4 4 在K8S中部署Prometheus 4 5 在K8S中部署Grafana与可视化 ...

  10. MyBatis:条件构造器QueryWrapper方法详解

    QueryWrapper 说明:      继承自 AbstractWrapper ,自身的内部属性 entity 也用于生成 where 条件及 LambdaQueryWrapper, 可以通过 n ...