[計算幾何]Last Stardust

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
要AB上側下側分開考慮,否則選到的四元組可能不合法

複習:樹狀數組求逆序對

int tree[NNN];
inline int lowbit(int x){return x&(-x);}
inline void update(int i){
	while(i<=tot){
		tree[i]+=1;
		i+=lowbit(i);
	}
}

inline int query(int i){
	int res=0;
	while(i>0){
		res+=tree[i];
		i-=lowbit(i);
	}
	return res;
}
update(x),ans+=i-query(x);
/*OR*/
ans+=i-query(x)-1,update(x);

ACcode

#include<bits/stdc++.h>
#define re register
#define in Read()
using namespace std;
inline int in{
	int i=0,f=1;char ch;
	while(!isdigit(ch)&&ch!='-')ch=getchar();
	if(ch=='-')ch=getchar(),f=-1;
	while(isdigit(ch))i=(i<<1)+(i<<3)+ch-48,ch=getchar();
	return i*f;
}

const int NNN=1e5+10;
const double eps=1e-7;
const double pi=3.1415;
int n,ans;
struct Point{
	double x,y;
	
	Point(){}
	Point(double _x,double _y){x=_x,y=_y;}
	inline void print(){printf("(%.5lf,%.5lf)\n",x,y);}
	
	friend inline Point operator + (const Point &u,const Point &v){return Point(u.x+v.x,u.y+v.y);}
	friend inline Point operator - (const Point &u,const Point &v){return Point(u.x-v.x,u.y-v.y);}
	friend inline Point operator * (const Point &u,const double &v){return Point(u.x*v,u.y*v);}
	friend inline Point operator / (const Point &u,const double &v){return Point(u.x/v,u.y*v);}
	friend inline double operator ^ (const Point &u,const Point &v){return u.x*v.y-u.y*v.x;}
	friend inline double operator % (const Point &u,const Point &v){return u.x*v.x+u.y*v.y;}
	
}A,B,p[NNN];

struct node{
	Point p;
	int id;
}now[NNN];
int tot;

inline double dis(Point u,Point v){return sqrt((u-v)%(u-v));}
inline double angle(Point u,Point v,Point w){return acos(((u-v)%(w-v))/(dis(u,v)*dis(w,v)));}

inline bool cmp1(const node &u,const node &v){return ((u.p-A)^(v.p-A))<0;}
inline bool cmp2(const node &u,const node &v){return ((u.p-B)^(v.p-B))<0;}
inline bool cmp3(const node &u,const node &v){return ((u.p-A)^(v.p-A))>0;}
inline bool cmp4(const node &u,const node &v){return ((u.p-B)^(v.p-B))>0;}

int tree[NNN];
inline int lowbit(int x){return x&(-x);}
inline void update(int i){
	while(i<=tot){
		tree[i]+=1;
		i+=lowbit(i);
	}
}

inline int query(int i){
	int res=0;
	while(i>0){
		res+=tree[i];
		i-=lowbit(i);
	}
	return res;
}

inline void upward(){
	memset(tree,0,sizeof(tree));tot=0;
	
	for(re int i=1;i<=n;++i)
		if(((B-A)^(p[i]-A))>0)
			now[++tot].p=p[i];
	
	sort(now+1,now+tot+1,cmp1);
	for(re int i=1;i<=tot;++i)now[i].id=i;
	
	sort(now+1,now+tot+1,cmp2);
	for(re int i=1;i<=tot;++i)
		update(now[i].id),ans+=i-query(now[i].id);
}

inline void downward(){
	memset(tree,0,sizeof(tree));tot=0;
	
	for(re int i=1;i<=n;++i)
		if(((B-A)^(p[i]-A))<0)
			now[++tot].p=p[i];
	
	sort(now+1,now+tot+1,cmp3);
	for(re int i=1;i<=tot;++i)now[i].id=i;
	
	sort(now+1,now+tot+1,cmp4);
	for(re int i=1;i<=tot;++i)
		update(now[i].id),ans+=i-query(now[i].id);
}

int main(){
	
	n=in;
	
	A.x=(double)in,A.y=(double)in;
	B.x=(double)in,B.y=(double)in;
	
	for(re int i=1;i<=n;++i)
		p[i].x=(double)in,p[i].y=(double)in;
	
	upward();
	downward();
	
	printf("%d\n",ans);
	
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章