http://acm.hdu.edu.cn/showproblem.php?pid=6127
每条线都能把点集分成两部分A和B,每两个点之间都有线段,所以穿过的线段权值和也就是A点集中点的权值和乘以B点集中点的权值和
极角排序,把y轴下面的点按原点中心对称过来,然后和y轴上面的点相反处理,标记一下就可以
#include<bits/stdc++.h>
#define N 50006
using namespace std;
const double pi=acos(-1.0);
struct point
{
long long x,y,v;
bool flag;
}a[N];
bool cmp(point x,point y)
{
double xx,yy;
xx=atan2((double)x.y,(double)x.x);
yy=atan2((double)y.y,(double)y.x);
return xx<yy;
}
int main()
{
int t,n;
long long sum1=0,sum2=0;
scanf("%d",&t);
while(t--)
{
sum1=0,sum2=0;
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%lld%lld%lld",&a[i].x,&a[i].y,&a[i].v);
if(a[i].y<0)
{
sum1+=a[i].v;
a[i].x*=-1;
a[i].y*=-1;
a[i].flag=false;
}
else a[i].flag=true,sum2+=a[i].v;
}
sort(a,a+n,cmp);
long long ans=sum1*sum2;
for(int i=0;i<n;i++)
{
// cout<<a[i].x<<" "<<a[i].y<<endl;
if(a[i].flag)
{
sum2-=a[i].v;
sum1+=a[i].v;
}
else
{
sum1-=a[i].v;
sum2+=a[i].v;
}
ans=max(ans,sum1*sum2);
}
cout<<ans<<endl;
}
return 0;
}