HDU 5784 How Many Triangles(极角排序)

来源:互联网 发布:linux怎么改文件夹名字 编辑:程序博客网 时间:2024/05/17 02:43

n
便C(n,3)
C(n,3)线
线

vwcross(w,v)<0wv
dot(v,w)0
线cross(v,w)==0dot(v,w)>0
=


代码:

#include <map>#include <set>#include <ctime>#include <stack>#include <queue>#include <cmath>#include <string>#include <vector>#include <cstdio>#include <cctype>#include <cstring>#include <sstream>#include <cstdlib>#include <iostream>#include <algorithm>#pragma comment(linker,"/STACK:102400000,102400000")using namespace std;#define   MAX           1000005#define   MAXN          1000005#define   maxnode       205#define   sigma_size    26#define   lson          l,m,rt<<1#define   rson          m+1,r,rt<<1|1#define   lrt           rt<<1#define   rrt           rt<<1|1#define   middle        int m=(r+l)>>1#define   LL            long long#define   ull           unsigned long long#define   mem(x,v)      memset(x,v,sizeof(x))#define   lowbit(x)     (x&-x)#define   pii           pair<int,int>#define   bits(a)       __builtin_popcount(a)#define   mk            make_pair#define   limit         10000//const int    prime = 999983;const int    INF   = 0x3f3f3f3f;const LL     INFF  = 0x3f3f;const double pi    = acos(-1.0);const double inf   = 1e18;const double eps   = 1e-4;const LL    mod    = 772002;const ull    mx    = 133333331;/*****************************************************/inline void RI(int &x) {      char c;      while((c=getchar())<'0' || c>'9');      x=c-'0';      while((c=getchar())>='0' && c<='9') x=(x<<3)+(x<<1)+c-'0'; }/*****************************************************/struct point{      LL x,y;      point(LL x=0,LL y=0):x(x),y(y){}      point operator - (const point &t)const{          return point(x-t.x,y-t.y);      }      LL operator * (const point &t)const{ /// 叉积 : 有向面积          return x*t.y-y*t.x;      }      LL operator ^ (const point &t)const{ /// 点积 : 有向长度          return x*t.x+y*t.y;      }      bool operator < (const point &t)const{ /// 极角排序          bool up[2]={0,0};          if(y>0 || (y==0 && x>0)) up[0]=1;          if(t.y>0 || (t.y==0 && t.x>0)) up[1]=1;          if(up[0]^up[1]) return up[0];          return (*this)*t ? (*this)*t>0 : ((*this)^(*this))<(t^t);      }  }p[MAX],v[MAX*2];  int main(){    //freopen("1002.in","r",stdin);    //freopen("froggy.out","w",stdout);    int n;    while(cin>>n){        for(int i=1;i<=n;i++) scanf("%I64d%I64d",&p[i].x,&p[i].y);        LL ans=(LL)n*(n-1)*(n-2)/6;        LL tmp=0;        for(int i=1;i<=n;i++){            int tot=0;            for(int j=1;j<=n;j++){                if(i==j) continue;                v[tot++]=p[j]-p[i];            }            sort(v,v+tot);            for(int j=0;j<tot;j++) v[j+tot]=v[j];            int num=0;            for(int j=1;j<tot;j++){                if(v[j]*v[j-1]==0&&(v[j]^v[j-1])>0) num++;//三点共线且同向,最后要去掉                else num=0;                tmp+=num;            }            int p1=0,p2=0;            for(int j=0;j<tot;j++){                while(p1<=j||(p1<j+tot&&v[p1]*v[j]<0&&(v[p1]^v[j])>0)) p1++;//左边并且是锐角                while(p2<=j||(p2<j+tot&&v[p2]*v[j]<0)) p2++;//左边,锐角+钝角+直角                ans-=p2-p1;            }        }        cout<<ans-tmp/2<<endl;    }    return 0;}
0 0
原创粉丝点击