李超树入门

就是用线段树去维护线段。就不写详解了

可以看传送门这篇博客。

#include<bits/stdc++.h>
#define il inline
#define pb push_back
#define ms(_data,v) memset(_data,v,sizeof(_data))
#define SZ(a) int((a).size())
using namespace std;
typedef long long ll;
typedef double db;
const ll inf=0x3f3f3f3f;
const int N=5e4+5; 
//il int Add(ll &x,ll y) {return x=x+y>=mod?x+y-mod:x+y;}
//il int Mul(ll &x,ll y) {return x=x*y>=mod?x*y%mod:x*y;}
struct Line{
	db k,b;
	int l,r;
};
struct node{
	Line li;
	bool fg;
}sg[N<<2];
il db calc(Line li,ll pos){
	return li.k*pos+li.b;
}
il long double cross (Line a,Line b){
	return (long double)(a.b-b.b)/(long double)(b.k-a.k);
}
il void update(int l,int r,int rt,Line nl){
	int mid=(l+r)>>1;
	if(nl.l<=l && nl.r>=r){
		if(!sg[rt].fg) sg[rt].fg=1,sg[rt].li=nl;
		else if(calc(nl,l)>calc(sg[rt].li,l) && calc(nl,r)>calc(sg[rt].li,r)) sg[rt].li=nl;
		else if(calc(nl,l)>calc(sg[rt].li,l) || calc(nl,r)>calc(sg[rt].li,r)){
			if(calc(nl,mid)>calc(sg[rt].li,mid)) swap(nl,sg[rt].li);
			if(cross(nl,sg[rt].li)<=mid) update(l,mid,rt<<1,nl);
			else update(mid+1,r,rt<<1|1,nl);
		}
		return ;
	}
	if(nl.l<=mid) update(l,mid,rt<<1,nl);
	if(nl.r>mid) update(mid+1,r,rt<<1|1,nl);
}
il db query(int l,int r,int rt,int P){
	if(l==r) return calc(sg[rt].li,P);
	int mid=(l+r)>>1;
	db ans=calc(sg[rt].li,P);
	if(P<=mid) ans=max(ans,query(l,mid,rt<<1,P));
	else ans=max(ans,query(mid+1,r,rt<<1|1,P));
	return ans;
} 
int T;
char op[10];
int main(){
//	std::ios::sync_with_stdio(0);cin.tie(0);
	scanf("%d",&T);
	double k,b;
	int x;
	while(T--){
		scanf("%s",op);
		if(op[0]=='P'){
			scanf("%lf%lf",&b,&k);
			b-=k;
			Line li=Line{k,b,1,N};
			update(1,N,1,li);
		}
		else{
			scanf("%d",&x);
			ll ans=(ll)query(1,N,1,x);
			printf("%lld\n",ans/100);	
		}
		
	}
	return 0;
}

BZOJ炸了,后面的题后面补

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值