zoukankan      html  css  js  c++  java
  • CF1025F Disjoint Triangles 题解

    Codeforces
    Luogu

    Description.

    (n) 个点,求有多少对三角形不相交。

    Solution.

    太妙了,没想到,想到三角形对数是 (O(n^6)) 的,发现怎么枚举都不行。

    考虑两个不相交的三角形,我们可以确定它们有恰好两条公切线,使得两个三角形在切线异侧。
    所以我们可以直接枚举公切线,然后再在左边选两个点,右边选两个点,可以直接组合数。
    公切线两侧的点数可以通过极角排序求出。
    每个三角形会被一条公切线少算两次,因为公切线上两个点有 (dbinom 21) 的方案。
    每条公切线会被多算两次,因为公切线会被它两个点分别确定一次。
    刚好抵消。

    Coding.

    点击查看代码
    //Coded by leapfrog on 2021.11.04 {{{
    //是啊,你就是那只鬼了,所以被你碰到以后,就轮到我变成鬼了
    #include<bits/stdc++.h>
    using namespace std;typedef long long ll;
    template<typename T>inline void read(T &x)
    {
    	x=0;char c=getchar(),f=0;
    	for(;c<48||c>57;c=getchar()) if(!(c^45)) f=1;
    	for(;c>=48&&c<=57;c=getchar()) x=(x<<1)+(x<<3)+(c^48);
    	f?x=-x:x;
    }
    template<typename T,typename...L>inline void read(T &x,L&...l) {read(x),read(l...);}//}}}
    const int N=2005;const long double Pi=acos(-1),eps=1e-9;
    int n,px[N],py[N];ll rs=0;long double an[N*2];
    inline ll C(ll a) {return 1ll*a*(a-1)/2;}
    int main()
    {
    	read(n);for(int i=1;i<=n;i++) read(px[i],py[i]);
    	for(int k=1,at=0;k<=n;k++,at=0)
    	{
    		for(int i=1;i<=n;i++) if(k^i) an[++at]=atan2(py[i]-py[k],px[i]-px[k]);
    		sort(an+1,an+at+1);for(int i=1;i<n;i++) an[++at]=an[i]+Pi*2;
    		for(int i=1,j=1;i<n;i++)
    		{
    			while(an[j]-an[i]<=Pi) j++;
    			int l=j-i-1,r=n-2-l;rs+=1ll*C(l)*C(r);
    		}
    	}return printf("%lld
    ",rs>>1),0;
    }
    
  • 相关阅读:
    大数加法、乘法实现的简单版本
    hdu 4027 Can you answer these queries?
    zoj 1610 Count the Colors
    2018 徐州赛区网赛 G. Trace
    1495 中国好区间 尺取法
    LA 3938 动态最大连续区间 线段树
    51nod 1275 连续子段的差异
    caioj 1172 poj 2823 单调队列过渡题
    数据结构和算法题
    一个通用分页类
  • 原文地址:https://www.cnblogs.com/pealfrog/p/15511502.html
Copyright © 2011-2022 走看看