【极角排序】【扫描线】hdu6127 Hard challenge

平面上n个点,每个点带权,任意两点间都有连线,连线的权值为两端点权值之积。没有两点连线过原点。让你画一条过原点直线,把平面分成两部分,使得直线穿过的连线的权值和最大。

就把点极角排序后,扫过去,一侧的点会跨过直线与另一侧的所有点形成连线。此时的答案为两侧的权值和之积,尝试用此更新最终答案。

#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
struct Point{
	ll x,y,val;
	int xx;
	Point(const ll &x,const ll &y){
		this->x=x;
		this->y=y;
	}
	Point(const ll &x,const ll &y,const ll &xx){
		this->x=x;
		this->y=y;
		this->xx=xx;
	}
	Point(){}
	void read(){
		scanf("%lld%lld%lld",&x,&y,&val);
		if(x>0 && y>=0){
			xx=1;
		}
		else if(x<=0 && y>0){
			xx=2;
		}
		else if(x<0 && y<=0){
			xx=3;
		}
		else{
			xx=4;
		}
	}
}p[100005];
bool operator < (const Point &a,const Point &b){
	return a.xx!=b.xx ? a.xx<b.xx : a.x*b.y-a.y*b.x>0;
}
ll sum[100005];
int n,T;
int main(){
	scanf("%d",&T);
	for(;T;--T){
		scanf("%d",&n);
		for(int i=1;i<=n;++i){
			p[i].read();
		}
		sort(p+1,p+n+1);
		for(int i=n+1;i<=2*n;++i){
			p[i]=p[i-n];
			p[i].xx=p[i-n].xx+4;
		}
		sum[1]=p[1].val;
		for(int i=2;i<=n*2;++i){
			sum[i]=p[i].val+sum[i-1];
		}
		ll ans=0;
		int i;
		for(i=1;i<=n;++i){
			Point *pt=upper_bound(p+1,p+n*2+1,Point(-p[i].x,-p[i].y,p[i].xx+2));
			ans=max(ans,(sum[pt-p-1]-sum[i-1])*(sum[n]-sum[pt-p-1]+sum[i-1]));
		}
		printf("%lld\n",ans);
	}
	return 0;
}
时间: 2024-12-25 04:50:12

【极角排序】【扫描线】hdu6127 Hard challenge的相关文章

【极角排序、扫描线】UVa 1606 - Amphiphilic Carbon Molecules(两亲性分子)

Shanghai Hypercomputers, the world's largest computer chip manufacturer, has invented a new class of nanoparticles called Amphiphilic Carbon Molecules (ACMs). ACMs are semiconductors. It means that they can be either conductors or insulators of elect

【极角排序+双指针线性扫】2017多校训练七 HDU 6127 Hard challenge

acm.hdu.edu.cn/showproblem.php?pid=6127 [题意] 给定平面直角坐标系中的n个点,这n个点每个点都有一个点权 这n个点两两可以连乘一条线段,定义每条线段的权值为线段两端点点权的乘积 现在要过原点作一条直线,要求这条直线不经过任意一个给定的点 在所有n个点两两连成的线段中,计算与这条直线有交点的线段的权值和 最大化这个权值和并输出 题目保证,给定的n个点不重合且任意两个点的连线不经过原点 [思路] 一条经过原点的直线把n个点分成两个半平面A,B 假设A中的点权

hdu6127 Hard challenge

地址:http://acm.split.hdu.edu.cn/showproblem.php?pid=6127 题目: Hard challenge Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others)Total Submission(s): 813    Accepted Submission(s): 329 Problem Description There are n po

poj2280Amphiphilic Carbon Molecules(极角排序)

链接 卡了几天的破题,对于hdu的那份数据,这就一神题.. 借助极角排序,枚举以每一个点进行极角排序,然后构造两条扫描线,一个上面一个下面,两条同时走,把上线和下线的点以及上线左边的点分别统计出来,如下图 样例3: 假如现在以d为p[0],那么所有可能结果一定是他与其他点的连线所分割的平面,那么首先以de为上线,下线的角度为上线+pi,两条线始终维护着这样的关系.de的下一个点为f,di的下一个点为c ,比较一下两者需要转的角度,选取较小角度转,注意一下相同的时候的处理. 1 #include

Hdu5032 极角排序+树状数组

题目链接 思路:参考了题解.对询问进行极角排序,然后用树状数组维护一下前缀和即可. /* ID: onlyazh1 LANG: C++ TASK: test */ #include<bits/stdc++.h> using namespace std; #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 typedef long long ll; const int maxn=1010; const int maxm=10

Codeforces Round #124 (Div. 1) C. Paint Tree(极角排序)

C. Paint Tree time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output You are given a tree with n vertexes and n points on a plane, no three points lie on one straight line. Your task is to paint

HDU Always Cook Mushroom (极角排序+树状数组)

Problem Description Matt has a company, Always Cook Mushroom (ACM), which produces high-quality mushrooms. ACM has a large field to grow their mushrooms. The field can be considered as a 1000 * 1000 grid where mushrooms are grown in grid points numbe

Codeforces 196C Paint Tree(贪心+极角排序)

题目链接 Paint Tree 给你一棵n个点的树和n个直角坐标系上的点,现在要把树上的n个点映射到直角坐标系的n个点中,要求是除了在顶点处不能有线段的相交. 我们先选一个在直角坐标系中的最左下角的点,把根结点放到这个点中,然后对剩下的点进行极角排序,按逆时顺序一个个塞进来,类似地递归处理. 这样就满足了题意. #include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for (int i(a); i <= (b

BZOJ 1132 [POI2008]Tro(极角排序)

[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1132 [题目大意] 平面上有N个点. 求出所有以这N个点为顶点的三角形的面积和(N<=3000) [题解] 我们发现直接枚举三个点计算会造成很大部分的叉积重复被计算, 因此我们枚举i,计算pj和pi点差的后缀和,我们发现对于固定边ij, 其与后面的枚举量相关贡献就为pj-pi和点差后缀和的叉积. 因此我们针对每个i进行后面数据的极角排序,O(n)计算与i相关的所有答案贡献. [代码]