码迷,mamicode.com
首页 > 其他好文 > 详细

JOISC2014K 二人の星座

时间:2020-02-21 17:47:15      阅读:87      评论:0      收藏:0      [点我收藏+]

标签:http   注意   span   turn   ons   set   for   枚举   class   

Link
注意到合法的一对三角形一定存在一对内公切线。
那么我们得到了一个\(O(n^3)\)的做法:枚举一条公切线的两个端点,计算公切线左侧和右侧的点数并统计答案。
考虑优化,先固定公切线的一端,然后把另一端按照该公切线的极角排序,那么利用前缀和就可以做到\(O(n^2\log n)\)了。

#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
typedef double db;
typedef long long i64;
const int N=3007;const db pi=acos(-1);
struct node{int x,y,c;db k;}a[N];
int s[2][3],p[N],x[N],y[N],c[N];
int operator<(const node&a,const node&b){return a.k<b.k;}
db mod(db x){return x<=0? x+pi:x;}
int read(){int x;scanf("%d",&x);return x;}
int main()
{
    int n=read();i64 ans=0;
    for(int i=1;i<=n;++i) x[i]=read(),y[i]=read(),c[i]=read();
    for(int t=1;t<=n;++t)
    {
    for(int i=1,j=0;i<=n;++i) if(i^t) a[++j]={x[i]-x[t],y[i]-y[t],c[i],mod(atan2(y[i]-y[t],x[i]-x[t]))};
    std::sort(a+1,a+n),memset(s,0,24);
    for(int i=1;i<n;++i) ++s[p[i]=a[i].y>0||(!a[i].y&&a[i].x<0)][a[i].c];
        for(int i=1;i<n;++i)
    {
        --s[p[i]][a[i].c];i64 r1=1,r2=1;
            for(int j=0;j<3;++j)
        {
                if(c[t]^j) r1*=s[0][j],r2*=s[1][j];
        if(a[i].c^j) r1*=s[1][j],r2*=s[0][j];
        }
        ans+=r1+r2,++s[p[i]^=1][a[i].c];
        }
    }
    printf("%lld\n",ans/4);
}

JOISC2014K 二人の星座

标签:http   注意   span   turn   ons   set   for   枚举   class   

原文地址:https://www.cnblogs.com/cjoierShiina-Mashiro/p/12342145.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!