码迷,mamicode.com
首页 > Web开发 > 详细

李超线段树 - JSOI2008BlueMary开公司

时间:2020-03-24 13:04:42      阅读:91      评论:0      收藏:0      [点我收藏+]

标签:模板题   维护   long   cout   动态插入   技术   mod   交点   odi   

李超线段树用来在平面内动态插入线段,求\(x=t\)直线与这些线段交点的最值

核心是维护每个区间的“最优势线段”,即终点位置处最高的线段,询问室对所有包含\(t\)的区间的最优势线段计算答案,最后取\(max\)

技术图片

模板题:JSOI2008BlueMary开公司

插入直线,求单点最大值

(看代码)

#include<bits/stdc++.h>
using namespace std;
const int N=50004;
#define lc (p<<1)
#define rc (p<<1|1)
int n=50000,Q;
char s[20];
double tk[N<<2],tb[N<<2];
bool tfl[N<<2];
void modify(int p,int l,int r,double k,double b){
	if(!tfl[p]){tfl[p]=1;tk[p]=k;tb[p]=b;return;}
	int mid=l+r>>1;
	double l1=l*k+b,r1=r*k+b;
	double l2=l*tk[p]+tb[p],r2=r*tk[p]+tb[p];
	if(l1<=l2&&r1<=r2)return;
	if(l1>l2&&r1>r2){tk[p]=k;tb[p]=b;return;}
	double x=(b-tb[p])/(tk[p]-k);
	if(l1>l2){
		if(x>mid){
			modify(rc,mid+1,r,tk[p],tb[p]);
			tk[p]=k;tb[p]=b;
		}
		else modify(lc,l,mid,k,b);
	}
	else{
		if(x>mid)modify(rc,mid+1,r,k,b);
		else{
			modify(lc,l,mid,tk[p],tb[p]);
			tk[p]=k;tb[p]=b;
		}
	}
}
double query(int p,int l,int r,int x){
	if(l==r)return tk[p]*x+tb[p];
	int mid=l+r>>1;
	double ret=tk[p]*x+tb[p];
	if(x<=mid)return max(ret,query(lc,l,mid,x));
	else return max(ret,query(rc,mid+1,r,x)); 
}
int main(){
	scanf("%d",&Q);
	while(Q--){
		scanf("%s",s);
		if(s[0]==‘P‘){
			static double x,y;
			scanf("%lf%lf",&x,&y);
			modify(1,1,n,y,x-y);
		} 
		else{
			static int x;
			scanf("%d",&x);
			cout<<(long long)(query(1,1,n,x)/100)<<"\n";
		}
	} 
	return (0-0);
}

李超线段树 - JSOI2008BlueMary开公司

标签:模板题   维护   long   cout   动态插入   技术   mod   交点   odi   

原文地址:https://www.cnblogs.com/aurora2004/p/12558122.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!