李超线段树板子

点击查看代码
#include<bits/stdc++.h>
using namespace std;

const int N=1e6+5;
const int mod=1e9;
const int p=39989;
const double eps=1e-9;

int n,m;
int ans,ansid;

int tcnt,rt;
struct lmy
{
	double k,b;
}a[N];
struct Tree
{
	int ls,rs,id;
}tr[N];

bool check(int i,int j,int x)
{
	if(a[i].k*x+a[i].b-a[j].k*x-a[j].b>eps) return 1;
	if(a[j].k*x+a[j].b-a[i].k*x-a[i].b>eps) return 0;

	return i<j;
}

void update(int &rt,int l,int r,int sl,int sr,int now)
{

	if(r<sl||sr<l) return ;
	if(!rt) rt=++tcnt;
	if(sl<=l&&r<=sr)
	{
		if(check(now,tr[rt].id,l)&&check(now,tr[rt].id,r))
		{
			tr[rt].id=now;
			return ;
		}
		if(check(tr[rt].id,now,l)&&check(tr[rt].id,now,r))
		{
			return ;
		}
		int mid=(l+r)>>1;
		if(check(now,tr[rt].id,mid)) swap(now,tr[rt].id);
		if(check(now,tr[rt].id,l)) update(tr[rt].ls,l,mid,sl,sr,now);
		if(check(now,tr[rt].id,r)) update(tr[rt].rs,mid+1,r,sl,sr,now);
	}
	else
	{
		int mid=(l+r)>>1;
		update(tr[rt].ls,l,mid,sl,sr,now);
		update(tr[rt].rs,mid+1,r,sl,sr,now);
	}
}


void solve(int rt,int l,int r,int s)
{
	// cout<<"!!!";
	if(!rt||r<s||s<l) return ;
	if(check(tr[rt].id,ansid,s)) ansid=tr[rt].id;
	if(l==r) return ;

	int mid=(l+r)>>1;
	solve(tr[rt].ls,l,mid,s);
	solve(tr[rt].rs,mid+1,r,s);
}

int main()
{
	// freopen("in.in","r",stdin);
	// freopen("out.out","w",stdout);

	int n;
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{

		int op;
		scanf("%d",&op);

		if(op==0)
		{
			int x=0; ansid=0;
			scanf("%d",&x); x=(x+ans-1)%p+1;

			solve(1,1,p,x); ans=ansid;
			printf("%d\n",ansid); 
		}
		else
		{
			
			int sx,sy,ex,ey;
			scanf("%d%d%d%d",&sx,&sy,&ex,&ey);
			
			sx=(sx+ans-1)%p+1; ex=(ex+ans-1)%p+1;
			sy=(sy+ans-1)%mod+1; ey=(ey+ans-1)%mod+1;

			if(ex<sx) swap(sx,ex),swap(sy,ey);

			if(ex!=sx) a[++m].k=1.0*(ey-sy)/(ex-sx),a[m].b=1.0*sy-a[m].k*sx;
			else a[++m].k=0,a[m].b=max(sy,ey);

			update(rt,1,p,sx,ex,m);
		}
	}
	return 0;
}
posted @ 2024-08-13 14:51  zhengchenxi  阅读(20)  评论(0编辑  收藏  举报