李超线段树 - JSOI2008BlueMary开公司

李超线段树用来在平面内动态插入线段,求\(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);
}

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

时间: 2024-08-12 05:44:45

李超线段树 - JSOI2008BlueMary开公司的相关文章

【BZOJ-1568】Blue Mary开公司 李超线段树 (标记可持久化)

1568: [JSOI2008]Blue Mary开公司 Time Limit: 15 Sec  Memory Limit: 162 MBSubmit: 557  Solved: 192[Submit][Status][Discuss] Description Input 第一行 :一个整数N ,表示方案和询问的总数. 接下来N行,每行开头一个单词“Query”或“Project”. 若单词为Query,则后接一个整数T,表示Blue Mary询问第T天的最大收益. 若单词为Project,则后

[CodeChef - STREETTA] The Street 李超线段树

大致题意: 给出两个序列A,B,A初始为负无穷,B初始为0,有三种操作 1.在A上区间[u,v]上加一个等差数列,取与原本A序列的最大值. 2.在B上区间[u,v]上加一个等差数列. 3.给出一个点X,询问A[X]+B[X]的值. 学习一个李超线段树就ojbk了,对于每次加入的等差数列,可以转化为y=a*i+b的一条线段,用李超线段树维护所有线段 所覆盖的区间即可.数据范围比较大,线段树可以动态开点,也可以离散化. 1 #include<cstdio> 2 #include<iostre

【BZOJ-4515】游戏 李超线段树 + 树链剖分 + 半平面交

4515: [Sdoi2016]游戏 Time Limit: 40 Sec  Memory Limit: 256 MBSubmit: 304  Solved: 129[Submit][Status][Discuss] Description Alice 和 Bob 在玩一个游戏. 游戏在一棵有 n 个点的树上进行.最初,每个点上都只有一个数字,那个数字是 123456789123456789. 有时,Alice 会选择一条从 s 到 t 的路径,在这条路径上的每一个点上都添加一个数字.对于路径上

【BZOJ4515】游戏,树链剖分+永久化标记线段树维护线段信息(李超线段树)

Time:2016.05.10 Author:xiaoyimi 转载注明出处谢谢 传送门 思路: 李超线段树 一开始听faebdc讲,并没有听的很懂ww 后来找到良心博文啊有木有 折越 首先可以把修改转换一下,因为那个dis非常不爽.显然s~t的路径有s~lca和lca~t组成.令d[x]表示x的深度,对于s~lca上面的点,修改的值相当于a*(d[s]-d[x])+b=-a*d[x]+(b-a*d[s]),lca~t上面的点的值相当于a*(d[s]+d[x]-2*d[lca])+b=a*d[x

李超线段树

李超线段树可以维护两两间至多有一个交点的函数覆盖,单点求极值问题. codechef NOV17 POLY 给定n个形如yi(x)=$a0+a1^x+a2x^2+a3x^3$的函数以及q个询问.每个询问给定整数t,你需要求出使得yi(t)最小化的函数yi. Lemma: Polynomial $y=x^3+ax^2+bx+c$ has at most one root greater than $k=\sqrt{\max(|b|,|c|)}+2$. Proof: Let $u\geq v >k\

CF932F(李超线段树+dp)

CF932F(李超线段树+dp) 此题又是新玩法, 李超线段树合并优化\(dp\) 一个显然的\(\Theta(n^2)dp\): \(dp[x]\)表示从x出发到叶子节点的最小代价 \(dp[x] = \min(dp[y] + a[x] * b[y]) ~~(y \in subtree(x))\) 如果我们将\(b[y]\)看成斜率, \(dp[y]\)看成纵截距, \(a[x]\)看成横坐标, 那么问题转为了在平面上有一些直线, 选出与直线\(x = a[x]\)相交的最靠下的点吗, 李超线

线段树应开内存

n*2的建树方法,适用于动态建树,就是说没有任何一个节点被浪费的建法.而这里我使用的,或者说大多数人使用的这种用x*2表示左子树 x*2+1表示右子树的建法,是不能只开到n*2的,因为有写节点没用到. 举个列子来说,假如线段树的n = 11,你认为应该建树为22或者23,保守点. 如果你要找[9,9]的区间,就会出现RTE了. 那么开多少才正确呢? 其实,应该是 2^ ( ceiling( log2(n) )+1 ), 即2的log2(n)的上取整加1次幂.

hdu 4027 Can you answer these queries? 线段树区间开根号,区间求和

Can you answer these queries? Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5195 Description A lot of battleships of evil are arranged in a line before the battle. Our commander decides to use our secret weapo

hdu 6183 Color it (线段树 动态开点)

Do you like painting? Little D doesn't like painting, especially messy color paintings. Now Little B is painting. To prevent him from drawing messy painting, Little D asks you to write a program to maintain following operations. The specific format o