李超线段树

技术文章 6个月前 完美者
1,916 0

标签:line   线段   ret   例题   swap   amp   ble   namespace   href   

参考:

https://oi-wiki.org/ds/li-chao-tree/

例题:

P4097 [HEOI2013]Segment

#include<bits/stdc++.h>
#define db double
const int p=39989;
using namespace std;

const int N=3e6+5;
int cnt,c[N];
struct A{
	db k,b; 
}poi[N];

inline bool jg(int a,int b,int x) {
	if(a==0) return 0;
	if(b==0) return 1;
	return poi[a].k*x+poi[a].b>poi[b].k*x+poi[b].b;
}

void add(int p,int l,int r,int x,int y,int t) {
	if(x>r||l>y) return;
	if(x<=l&&r<=y) {
		if(jg(c[p],t,l)&&jg(c[p],t,r)) return;
		if(jg(t,c[p],l)&&jg(t,c[p],r)) {
			c[p]=t; return;
		}
		int mid=l+r>>1;
		if(jg(t,c[p],mid)) swap(t,c[p]);
		if(jg(t,c[p],l)) add(p<<1,l,mid,x,y,t);
			else add(p<<1|1,mid+1,r,x,y,t);
		return;
	}
	int mid=l+r>>1;
	add(p<<1,l,mid,x,y,t),add(p<<1|1,mid+1,r,x,y,t);
}

int ask(int p,int l,int r,int x) {
	if(x<l||x>r) return 0;
	if(l==r) {
		return c[p];
	}
	int mid=l+r>>1;
	if(x<=mid) {
		int tt=ask(p<<1,l,mid,x);
		if(jg(tt,c[p],x)) return tt;
		return c[p];
	}
	int tt=ask(p<<1|1,mid+1,r,x);
	if(jg(tt,c[p],x)) return tt;
	return c[p];
}
int main() {
	int ans=0; int n=40000;
	int T; scanf("%d",&T);
	while(T--) {
		int op; scanf("%d",&op);
		if(!op) {
			int x; scanf("%d",&x);
			x=(x+ans-1)%p+1;
			printf("%d\n",ans=ask(1,1,n,x));
		} else {
			int x1,y1,x2,y2; scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
			x1=(x1+ans-1)%p+1,y1=(y1+ans-1)%1000000000+1;
			x2=(x2+ans-1)%p+1,y2=(y2+ans-1)%1000000000+1;
			if(x2<x1) swap(x1,x2),swap(y1,y2);
			poi[++cnt]=x1==x2?(A){0,max(y1,y2)}:(A){(db)(y2-y1)/(x2-x1),-(db)(y2-y1)/(x2-x1)*x1+y1};
			add(1,1,n,x1,x2,cnt);
		}
	}
	return 0;
}

李超线段树

标签:line   线段   ret   例题   swap   amp   ble   namespace   href   

原文地址:https://www.cnblogs.com/wsfwsf/p/14290134.html

版权声明:完美者 发表于 2021-01-18 11:39:35。
转载请注明:李超线段树 | 完美导航

暂无评论

暂无评论...