【BZOJ5099】[POI2018]Pionek

Description

在无限大的二维平面的原点(0,0)放置着一个棋子。你有n条可用的移动指令,每条指令可以用一个二维整数向量表示。每条指令最多只能执行一次,但你可以随意更改它们的执行顺序。棋子可以重复经过同一个点,两条指令的方向向量也可能相同。你的目标是让棋子最终离原点的欧几里得距离最远,请问这个最远距离是多少?

Input

第一行包含一个正整数n(n<=200000),表示指令条数。
接下来n行,每行两个整数x,y(|x|,|y|<=10000),表示你可以从(a,b)移动到(a+x,b+y)。

Output

输出一行一个整数,即最大距离的平方。

Sample Input

5
2 -2
-2 -2
0 2
3 1
-3 1

Sample Output

26

HINT

题解:假如我们已经确定了最终向量的方向,那么我们就会选择所有在这个方向上投影为正的向量。于是我们将所有向量按极角排序,然后枚举所有方向,用前缀和维护向量的和。可以先将序列倍长,然后用双指针法扫一遍即可。

不过需要注意的是,我们枚举的方向不仅是所有向量的方向,还有所有向量之间间隔的方向,所以我们在每个指针移动的时候都更新一下答案即可。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
#define pi acos(-1.0)
using namespace std;
typedef long long ll;
const int maxn=200010;
int n;
ll ans;
struct node
{
int x,y;
double a;
}p[maxn<<1];
ll sx[maxn<<1],sy[maxn<<1];
bool cmp(const node &a,const node &b)
{
return a.a<b.a;
}
inline void check(int l,int r)
{
if(l<=r) ans=max(ans,(sx[r]-sx[l-1])*(sx[r]-sx[l-1])+(sy[r]-sy[l-1])*(sy[r]-sy[l-1]));
}
inline int rd()
{
int ret=0,f=1; char gc=getchar();
while(gc<'0'||gc>'9') {if(gc=='-') f=-f; gc=getchar();}
while(gc>='0'&&gc<='9') ret=ret*10+(gc^'0'),gc=getchar();
return ret*f;
}
int main()
{
n=rd();
int i,j;
for(i=1;i<=n;i++) p[i].x=rd(),p[i].y=rd(),p[i].a=atan2(p[i].x,p[i].y),p[i+n]=p[i],p[i+n].a+=2*pi;
sort(p+1,p+2*n+1,cmp);
for(i=1;i<=2*n;i++) sx[i]=sx[i-1]+p[i].x,sy[i]=sy[i-1]+p[i].y;
for(i=j=1;i<=2*n;i++)
{
for(;j<i&&p[j].a<=p[i].a-pi;j++,check(j,i-1));
check(j,i);
}
for(;j<=2*n;check(j,2*n),j++);
printf("%lld",ans);
return 0;
}//2 1 10 1 -10

【BZOJ5099】[POI2018]Pionek 几何+双指针的更多相关文章

  1. bzoj5099 [POI2018]Pionek 双指针

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=5099 题解 这道题做法似乎挺单一的. (一开始想了个假做法 向量和的长度等于所有向量在其方向上 ...

  2. bzoj5099: [POI2018]Pionek

    Description 在无限大的二维平面的原点(0,0)放置着一个棋子.你有n条可用的移动指令,每条指令可以用一个二维整数向量表 示.每条指令最多只能执行一次,但你可以随意更改它们的执行顺序.棋子可 ...

  3. [POI2018]Pionek

    [POI2018]Pionek 题目大意: 在无限大的二维平面的原点放置着一个棋子.你有\(n(n\le2\times10^5)\)条可用的移动指令,每条指令可以用一个二维整数向量表示.请你选取若干条 ...

  4. bzoj 5099 [POI2018]Pionek 计算几何 极角排序

    [POI2018]Pionek Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 269  Solved: 80[Submit][Status][Disc ...

  5. 【bzoj5099】[POI2018]Pionek 双指针法

    题目描述 给你 $n$ 个平面向量,选出它们中的一部分,使得它们的和的长度最大.求这个最大长度的平方. 输入 第一行包含一个正整数n(n<=200000),表示指令条数. 接下来n行,每行两个整 ...

  6. bzoj 5099: [POI2018]Pionek

    题解: 还是比较简单的一道题 考虑现在有一个向量,当且仅当下一个向量与它夹角<90度这个向量的模长才会增加 接下来怎么做呢 如果我们去枚举初始向量,向量方向会随着新增向量而变化 随着不断顺时针的 ...

  7. BZOJ 5099: Pionek(双指针)(占位)

    pro:有N个向量,你可以选择一些向量,使得其向量和离原点最远. 输出这个欧几里得距离的平方. sol:(感觉网上的证明都不是很充分,我自己也是半信半疑吧)日后证明了再补. #include<b ...

  8. POI2018

    [BZOJ5099][POI2018]Pionek(极角排序+two pointers) 几个不会严谨证明的结论: 1.将所有向量按极角排序,则答案集合一定是连续的一段. 当答案方向确定时,则一个向量 ...

  9. [BZOJ5099]Pionek

    Description 给 \(n\) (\(n\le 2\times 10 ^5\)) 个向量,现在你在 \((0,0)\) ,选择一些向量使你走的最远. Solution 自己的想法:按极角排序后 ...

随机推荐

  1. Hibernate- 开发环境准备

    数据库:两张表,两者通过publisher_id构成关联关系. Book(图书表) CREATE TABLE `t_book` ( `id` int(11) NOT NULL AUTO_INCREME ...

  2. node-webkit播放目录下所有网页文件

    1.编写index.html文件 这里我们需要播放某一个目录下所有的网页文件,要做到切换不同的网页,可以在index.html中使用iframe.通过js动态改变iframe的src属性,从而动态地切 ...

  3. 事件总线demo

    经过几天的努力拜读大牛高手文章,终于对事件总线有所了解,特此记录下来,以免忘记 1.定义相关的接口: A  事件接口 public interface IDomainEvent { DateTime ...

  4. 关于Cocos2d-x的粒子系统

    1.cocos2d-x有一些自带的粒子效果,以后可以用到.当然,也可以自己定义一些粒子,不过要定义的话,虽然可以用cpp文件自己写,但是没有可视化的调节,还要设定各种奇怪的参数,是非常困难的.可以用一 ...

  5. asp.net 后端验证

    using EntryRegistration.Filters; using EntryRegistration.Models.Entity; using System; using System.C ...

  6. c#调用cmd

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.D ...

  7. vs2008 调试时不会命中断点,源代码与原始版本不同,解决办法

    当前不会命中断点,源代码与原始版本不同,解决办法 1.应该是自己一行里写的代码太长了 格式化一下 或者 换下行 2. VC直接把整个文件格式化了一次,断点就可以用了 菜单:编辑-〉高级-〉设置选定内容 ...

  8. ADO连接数据库【msado15.dll】

    Microsoft ActiveX Data Objects (ADO) 注册表查看ADO版本:HKEY_LOCAL_MACHINE\Software\Microsoft\DataAccess下有Ve ...

  9. shell脚本中判断一个字符串是否是空字符串

    需求说明: 在写脚本的时候,有的时候,需要判断一个字符串是否为空,因此,在此写出如何判断一个字符串为空的方法. 简单来说,就是字符串的比较. 测试脚本: 以下的脚本用于测试str_1和str_2是否是 ...

  10. Java 应用程序设计规范

    1.能在程序中取的产生就从程序中取.不用客户输入(减少客户输入). 比如客户号 信息 等. 2.如果有参数输入尽可能减少参数输入的个数(4个->0个): 3.验证入参(尽可能的实现输入参数的正确 ...