P4293 [WC2010]能量场
P4293 [WC2010]能量场
题意
给你 \(n\) 个粒子,每个粒子有两个权值 \(m_i,c_i\) 每个相邻有序对 \((a,b)\) 会产生 \(m_am_b(c_a-c_b)\) 的贡献。现让你处理两个问题:
- 找出一个有序对使贡献最大。
- 找出一个序列成环后贡献和最大。
思路
我们将贡献转化一下:
\]
那么这就形成了一个叉积的形式。即将每个点 \(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]能量场的更多相关文章
- BZOJ1758: [Wc2010]重建计划
题解: 这题我居然做了一星期?... 平均值的极值其实也可以算是一种分数规划,只不过分母上b[i]=1 然后我们就可以二分这个值.类似与 HNOI最小圈 如果没有 链的长度的限制的话,我们直接两遍df ...
- 洛谷 P4292 [WC2010]重建计划 解题报告
P4292 [WC2010]重建计划 题目描述 \(X\)国遭受了地震的重创, 导致全国的交通近乎瘫痪,重建家园的计划迫在眉睫.\(X\)国由\(N\)个城市组成, 重建小组提出,仅需建立\(N-1\ ...
- [WC2010]重建计划 长链剖分
[WC2010]重建计划 LG传送门 又一道长链剖分好题. 这题写点分治的人应该比较多吧,但是我太菜了,只会长链剖分. 如果你还不会长链剖分的基本操作,可以看看我的长链剖分总结. 首先一看求平均值最大 ...
- 【BZOJ1758】【WC2010】重建计划(点分治,单调队列)
[BZOJ1758][WC2010]重建计划(点分治,单调队列) 题面 BZOJ 洛谷 Description Input 第一行包含一个正整数N,表示X国的城市个数. 第二行包含两个正整数L和U,表 ...
- 「WC2010」重建计划(长链剖分/点分治)
「WC2010」重建计划(长链剖分/点分治) 题目描述 有一棵大小为 \(n\) 的树,给定 \(L, R\) ,要求找到一条长度在 \([L, R]\) 的路径,并且路径上边权的平均值最大 \(1 ...
- bzoj 1758 [Wc2010]重建计划 分数规划+树分治单调队列check
[Wc2010]重建计划 Time Limit: 40 Sec Memory Limit: 162 MBSubmit: 4345 Solved: 1054[Submit][Status][Disc ...
- bzoj1758 [Wc2010]重建计划 & bzoj2599 [IOI2011]Race
两题都是树分治. 1758这题可以二分答案avgvalue,因为avgvalue=Σv(e)/s,因此二分后只需要判断Σv(e)-s*avgvalue是否大于等于0,若大于等于0则调整二分下界,否则调 ...
- bzoj 1758: [Wc2010]重建计划
Description Input 第 一行包含一个正整数N,表示X国的城市个数. 第二行包含两个正整数L和U,表示政策要求的第一期重建方案中修建道路数的上下限 接下来的N-1行描述重建小组的原有方案 ...
- BZOJ1758: [Wc2010]重建计划(01分数规划+点分治+单调队列)
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1758 01分数规划,所以我们对每个重心进行二分.于是问题转化为Σw[e]-mid>=0, ...
随机推荐
- python+selenium基础篇,切入切出frame
1.首先制作一个html的文件,代码如下 <!DOCTYPE html> <html> <head> <title>Frame_test</tit ...
- HashMap底层实现原理及面试常见问题
HashMap底层源码分析 1.HashMap底层采用的存储结构 1.在JDK1.7及之前采用的存储结构是数组+链表 2.到了JDK1.8之后采用的是数组+链表+红黑树 2.HashMap实现的原理 ...
- Atcoder rc122-c Calculator 斐波那契
传送门 题解 先说结论: 任意正整数可以拆分成若干个斐波那契数 斐波那契数列: 1 1 2 3 5 8 13 21 34 例 17 = 13 + 3 + 1 看上去是对的,怎么证明呢? 首先假如每一个 ...
- StackOverflow上面 7个最好的Java答案
StackOverflow发展到目前,已经成为了全球开发者的金矿.它能够帮助我们找到在各个领域遇到的问题的最有用的解决方案,同时我们也会从中学习到很多新的东西.这篇文章是在我们审阅了StackOver ...
- Java将字符串反转的7种方法
/方法1 递归方法 public static String reverse1(String s) { int length = s.length(); if(length <= 1){ ret ...
- 【题解】Luogu P2875 [USACO07FEB]牛的词汇The Cow Lexicon
题目描述 Few know that the cows have their own dictionary with W (1 ≤ W ≤ 600) words, each containing no ...
- NOIP模拟测试6「那一天我们许下约定(背包dp)·那一天她离我而去」
那一天我们许下约定 内部题,题干不粘了. $30分算法$ 首先看数据范围,可以写出来一个普通dp #include<bits/stdc++.h> #define ll int #defin ...
- golang中的defer和return的执行顺序
结论 go中是先给return准备返回值,再根据defer先进后出的规则执行,最后将返回值返回给调用者 测试用例1验证分析 代码片段如下: func foo_1() (err error) { def ...
- react 中的PropTypes与DefaultProps
每个组件都有自己的props参数,这参数是从父组件接收的一些属性.那我们应该如何对参数的类型做校验,如何定义参数的默认值呢? 1.使用PropTypes校验父组件传过来的参数是否合法 import P ...
- ES6学习笔记之函数(二)
5.作用域 使用默认参数时,参数会形成一个独立的作用域,此作用域与函数体中的作用域是平行关系,互不影响. var x = 1; function show(x, y= function () { x= ...