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. fiddler概念及原理

    一.什么是fiddler? fiddler是位于客户端与服务器端的HTTP代理,它能够记录客户端与服务器之间所有的HTTP请求,可以针对特定的HTTP请求,分析请求数据,设置断点,调试WEB应用,修改 ...

  2. 【Azure 机器人】微软Azure Bot 编辑器系列(1) : 创建一个天气对话机器人(The Bot Framework Composer tutorials)

    欢迎来到微软机器人编辑器使用教程,从这里开始,创建一个简单的机器人. 在该系列文章中,每一篇都将通过添加更多的功能来构建机器人.当完成教程中的全部内容后,你将成功的创建一个天气机器人(Weather ...

  3. 魔镜魔镜,今天有雨吗?——GitHub 热点速览 v.21.25

    作者:HelloGitHub-小鱼干 上周智能驾驶项目的作者曾经做过一个透明小电视机,同透明电视机类似 MagicMirror 也是一个神奇的智能项目,使用它进行模块定制开发,你将拥有一块非常酷炫的智 ...

  4. noip模拟7[匹配·回家·寿司]

    这次考试状态好像还是没有回来,只拿了55pts,还全是第一题的功劳,就是一个小KMP,然后还让我给打错了 就很难受,while打成了if,然后wa掉45分考完立马拿回来了,悔死了,害 第二题爆零了,为 ...

  5. 手写Spring,定义标记类型Aware接口,实现感知容器对象

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 同事写的代码,我竟丝毫看不懂! 大佬的代码,就像 "赖蛤蟆泡青蛙,张的丑玩 ...

  6. excel打印出现多余空白页

    问题: 解决方法一:设置打印区域 步骤:选择需要打印的内容--页面布局--打印区域--设置打印区域即可 解决方法二:删除多余的打印空白页 步骤:视图--分页预览--选中多余的空白页删除即可

  7. 跟我一起学 Go 系列:gRPC 拦截器

    Go gRPC 学习系列: 跟我一起学Go系列:gRPC 入门必备 第一篇内容我们已经基本了解到 gRPC 如何使用 .对应的三种流模式.现在已经可以让服务端和客户端互相发送消息.本篇仍然讲解功能性的 ...

  8. 100、nginx_https安全链接配置

    100.1. tcp的三次握手和四次挥手的过程: 1.三次握手(建立连接): 第一次:建立连接时,客户端发送SYN包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认: 第二次:服务器 ...

  9. oracle行转列实现

    1.新建测试表 create table TEST_TABLE( T1 VARCHAR2(10),--姓名 T2 VARCHAR2(10),--科目 T3 VARCHAR2(10)--成绩 ) 2.插 ...

  10. 基于Yarp实现内网http穿透

    Yarp介绍 YARP是微软开源的用来代理服务器的反向代理组件,可实现的功能类似于nginx. 基于YARP,开发者可以非常快速的开发一个性能不错的小nginx,用于代理http(s)请求到上游的ht ...