P3316 [SDOI2014] 里面还是外面

\lxl/\lxl/
判断一个点是否在多边形内通常的做法是引一条射线,算出交点个数奇偶性。
那么我们就可以令这条射线平行于\(y\)轴,现在只用快速算出这样的交点数就好了。
考虑将多边形的每条边抽离。按\(x\)坐标建立线段树后,将线段插入到\(O(\log n)\)个线段树节点上,这样每个节点所代表的\(x\)坐标区间内,线段都是贯穿的,并且不相交(除了顶点)。
因为我们要支持查询某个\(x=P\)直线与若干线段交点中,纵坐标\(\le K\)的个数,线段需要带修,所以我们对每个线段树节点开一棵平衡树维护插入、删除、查排名操作就好了。
PEKKA说要用vector写平衡树,确实能冲。
代码:

#include<bits/stdc++.h>
#define db long double
using namespace std;
using ll=long long;
char *p1,*p2,buf[100000];
#define gc() (p1==p2 && (p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++)
inline int read(){
	int x=0,f=1;char c=gc();
	for(;c<'0'||c>'9';c=gc())if(c=='-')f=-1;
	for(;c>='0'&&c<='9';c=gc())x=(x<<1)+(x<<3)+c-'0';
	return x*f;
}
const int N=2e5+5;
const int INF=1e9,V=1e9;
int n,q;
struct Point{
	int x,y;
}p[N];
int pcnt,lcnt;
unordered_map<ll,int>um_p,um_l;
struct Line{
	Point st,ed;
	Line(){}
	Line(Point ps,Point pd){
		st=ps,ed=pd;
		if(st.x>ed.x)swap(st,ed);
	}
	inline db gt(int pos){
		db k=1.0*(ed.y-st.y)/(ed.x-st.x);
		db b=ed.y-k*ed.x;
		return pos*k+b; 
	}
	inline bool bon(int x,int y){
		if(x<st.x||x>ed.x)return 0;
		return 1ll*(st.x-x)*(ed.y-st.y)==1ll*(ed.x-st.x)*(st.y-y);
	}
}li[N];
inline ll ghas(int x,int y){return 1ll*(INF+1)*x+y;}
inline int gpo(int x,int y){return um_p[ghas(x,y)];}
inline int glin(int x,int y){if(x>y)swap(x,y);return um_l[ghas(x,y)];}
bool mbo;
struct V_Treap{
	int lp,rp;
	struct pnod{
		int id,pos;
		inline bool operator <(const pnod P){return li[id].gt(pos)<li[P.id].gt(pos);}
	};
	inline void init(int pl,int pr){lp=pl,rp=pr;}
	vector<pnod>tr;
	inline void ins(int x){
		tr.insert(lower_bound(tr.begin(),tr.end(),(pnod){x,lp}),{x,lp});
	}
	inline void era(int x){
		tr.erase(lower_bound(tr.begin(),tr.end(),(pnod){x,lp}));
	}
	inline int qry(int x,int y){
		if(tr.empty())return 0; 
		int l=0,r=(int)tr.size()-1;
		while(l<=r){
			int mid=(l+r)>>1;
			if(li[tr[mid].id].bon(x,y)){
				mbo=1;
				return 0;
			}
			if(li[tr[mid].id].gt(x)-1e-9<=y)l=mid+1;
			else r=mid-1;
		}
		return l;
	}
}trp[N<<6];
struct node{
	int ls,rs;
}tr[N<<6];
int cnt;
struct SGT{
	#define ls(p) tr[p].ls
	#define rs(p) tr[p].rs
	int rt;
	void upd(int &p,int l,int r,int x,int y,int v,int w){
		if(!p)p=++cnt,trp[p].init(l,r);
		if(x<=l&&r<=y)return w==1?trp[p].ins(v):trp[p].era(v);
		if(r==l+1)return ;
		int mid=(l+r)>>1;
		if(x<=mid)upd(ls(p),l,mid,x,y,v,w);
		if(y>=mid)upd(rs(p),mid,r,x,y,v,w);
	}
	inline void ins(int v){return upd(rt,0,V,li[v].st.x,li[v].ed.x,v,1);}
	inline void del(int v){return upd(rt,0,V,li[v].st.x,li[v].ed.x,v,-1);}
	int qry(int p,int l,int r,int x,int y){
		if(l>x||r<x)return 0;
		if(!p)return 0;
		if(l==r)return trp[p].qry(x,y);
		int res=trp[p].qry(x,y),mid=(l+r)>>1;
		res+=qry(ls(p),l,mid,x,y);
		res+=qry(rs(p),mid,r,x,y);
		return res;
	}
	inline int qry(int x,int y){return qry(rt,0,V,x,y);}
}T;
inline string to(int x){
	if(x==1)return "in";
	if(x==0)return "out";
	return "bd";
}
int main(){
	ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
	n=read();
	for(int i=1;i<=n;i++){
		p[i].x=read(),p[i].y=read();
		um_p[ghas(p[i].x,p[i].y)]=i;
	}
	for(int i=1;i<=n;i++){
		int nxt=i%n+1;
		um_l[ghas(min(i,nxt),max(i,nxt))]=i;
		li[i]=Line(p[i],p[i%n+1]);
		T.ins(i);
	}
	int las=T.qry(0,0)&1;
	if(mbo==1)las=2;
	pcnt=lcnt=n;
	int lasx=0,lasy=0;
	q=read();
	int op,r,xa,ya,xb,yb,xc,yc,x,y;
	for(int i=1;i<=q;i++){
		mbo=0;
		op=read();
		if(op==0){
			r=read(),xa=read(),ya=read(),xb=read(),yb=read(),xc=read(),yc
=read();
			if(las==1){
				x=(r*lasx+xa)%V;
				y=(r*lasy+ya)%V;
			}
			else if(las==0){
				x=(r*lasx+xb)%V;
				y=(r*lasy+yb)%V;
			}
			else{
				x=(r*lasx+xc)%V;
				y=(r*lasy+yc)%V;
			}
			lasx=x,lasy=y;
			las=T.qry(x,y);
			las&=1;
			if(mbo==1)las=2;
			cout<<to(las)<<"\n";
		}
		else{
			xa=read(),ya=read(),xb=read(),yb=read(),xc=read(),yc
=read();
			int ia=gpo(xa,ya),ib=gpo(xb,yb);
			p[++pcnt]={xc,yc};
			um_p[ghas(xc,yc)]=pcnt;
			int &v=um_l[ghas(min(ia,ib),max(ia,ib))];
			T.del(v);v=0;
			li[++lcnt]=Line(p[ia],p[pcnt]),um_l[ghas(ia,pcnt)]=lcnt,T.ins(lcnt);
			li[++lcnt]=Line(p[ib],p[pcnt]),um_l[ghas(ib,pcnt)]=lcnt,T.ins(lcnt);
		}
	}
	return 0;
}
posted @ 2025-03-30 20:29  wjwweiwei  阅读(28)  评论(0)    收藏  举报