BZOJ 3165: [Heoi2013]Segment

超哥线段树

#include<cstdio>
#include<algorithm>
using namespace std;
const int lim=39989;
const int Mod=1e9;
int ansid,ANS[2000005],Max[100005],Maxid[100005];
double ans;
struct node{
	double k,b;
}Line[2000005];
inline double check(node a,node b){
	return (a.b-b.b)/(b.k-a.k);
}
inline double calc(double x,node line){
	return line.k*x+line.b;
}
inline void update(int t,node line,int ID){
	Line[t]=line,ANS[t]=ID;
}
inline void insert(int t,int l,int r,int x,int y,node line,int ID){
	if (l>y || r<x) return;
	if (l>=x && r<=y){
		double Lmax=calc(l,line),Rmax=calc(r,line);
		double Lt=calc(l,Line[t]),Rt=calc(r,Line[t]);
		if (Lmax<=Lt && Rmax<=Rt) return;
		else if (Lmax>Lt && Rmax>Rt) update(t,line,ID);
		else{
			int mid=(l+r)>>1;
			double Key=check(line,Line[t]);
			node To=line;
			int Toid=ID;
			if (Key<=mid) {
				if (Lmax<Lt) {
					To=Line[t],Toid=ANS[t];
					update(t,line,ID);
				}
				insert(t<<1,l,mid,x,y,To,Toid);
			}
			else {
				if (Rmax<Rt){
					To=Line[t],Toid=ANS[t];
					update(t,line,ID);
				}
				insert(t<<1|1,mid+1,r,x,y,To,Toid);
			}
		}
		return;
	}
	int mid=(l+r)>>1;
	insert(t<<1,l,mid,x,y,line,ID);
	insert(t<<1|1,mid+1,r,x,y,line,ID);
}
void query(int t,int l,int r,int key){
	double Key=calc(key,Line[t]);
	if (Key>ans || (Key==ans && ANS[t]<ansid)) ans=Key,ansid=ANS[t];
	if (l==r) return;
	int mid=(l+r)>>1;
	if (key<=mid) query(t<<1,l,mid,key);
	else query(t<<1|1,mid+1,r,key);
}
int main(){
	int q;
	scanf("%d",&q);
	int Lastans=0,Num=0;
	for (int i=1; i<=lim; i++) Max[i]=-1e9;
	while (q--){
		int cas;
		scanf("%d",&cas);
		if (!cas){
			int X;
			scanf("%d",&X);
			X=(X+Lastans-1)%lim+1;
			ans=ansid=0;
			query(1,1,lim,X);
			if (Max[X]>ans || (Max[X]==ans && Maxid[X]<ansid)) ans=Max[X],ansid=Maxid[X];
			Lastans=ansid;
			printf("%d\n",Lastans);
		}
		else{
			int x0,y0,x1,y1;
			scanf("%d%d%d%d",&x0,&y0,&x1,&y1);
			x0=(x0+Lastans-1)%lim+1,y0=(y0+Lastans-1)%Mod+1;
			x1=(x1+Lastans-1)%lim+1,y1=(y1+Lastans-1)%Mod+1;
			if (x0>x1) swap(x0,x1),swap(y0,y1);
			Num++;
			if (x0==x1){
				int val=max(y0,y1);
				if (val>Max[x0]) Max[x0]=val,Maxid[x0]=Num;
			}
			else{
				double K=((double)y1-y0)/(x1-x0);
				double B=y0-x0*K;
				insert(1,1,lim,x0,x1,(node){K,B},Num);
			}
		}
	}
	return 0;
}

  

posted @ 2018-10-24 11:06  ~Silent  阅读(137)  评论(0编辑  收藏  举报
Live2D