首页 > 其他分享 >李超线段树学习笔记

李超线段树学习笔记

时间:2023-08-07 17:23:46浏览次数:37  
标签:rt 线段 李超 笔记 yy xx e1 e2

用途

李超线段树的用法非常固定,一般就是让你求对于给出的一些线段或直线中,对于某个x最大的y是那个。

通常可以用于斜率优化。

而其的时间复杂度是 \(O(n\log n^2)\)

思路

注:下文默认是线段,因为直线也只用改一下就行了。

我们建立一颗线段树,每个节点保存在当前区间,当x=mid时最大的线段的编号。

然后每次将两条线段进行比较,因为两条线段要么被另一条线段完全覆盖,要么只会覆盖左右区间中的一个(因为交点最多只有一个)。所以对于完全覆盖的,直接选择那一条直线,覆盖一半的,递归查找就行。

对于标记下传的话不太好直接下传,我们可以用标记永久化来做即可。注意因为是浮点数计算,注意要使用eps来判相等。

code

点击查看代码
#include<bits/stdc++.h>
using namespace std;
int n;
const int N=100011;
int p[N<<2];
double k[N],b[N];
double clac(int id,int x){
	return 1.0*k[id]*x+1.0*b[id];
}
int cnt=0;
struct dot{
	int xx,yy;
}e1,e2;
double eps=0.0000000001;
void update(int rt,int l,int r,int u){
	int mid=(l+r)>>1;
	if(!p[rt]){
		p[rt]=u;
//		cout<<"u:"<<u<<endl;
		return ;
	}
	if(l==r){
		int f=clac(u,mid);//bianhao
		int g=clac(p[rt],mid);
		if(f-g>eps)swap(p[rt],u);
		if(abs(f-g)<eps&&u<p[rt])p[rt]=u;
		return ;
	}
	else{
//		cout<<"cnt:"<<u<<" "<<p[rt]<<" "<<l<<" "<<r<<endl;
		double f=clac(u,mid);//bianhao
		double g=clac(p[rt],mid);
//		cout<<"l,r.f,g:"<<l<<" "<<r<<" "<<f<<" "<<g<<endl;
		if(f-g>eps)swap(p[rt],u);
//		cout<<u<<" "<<p[rt]<<endl;
		if(clac(u,l)-clac(p[rt],l)>eps||(abs(clac(u,l)-clac(p[rt],l))<eps&&u<p[rt]))update(rt<<1,l,mid,u);
		if(clac(u,r)-clac(p[rt],r)>eps||(abs(clac(u,r)-clac(p[rt],r))<eps&&u<p[rt]))update(rt<<1|1,mid+1,r,u);
		
	}
}
void change(int rt,int l,int r,int L,int R){
	if(L<=l&&r<=R){
//		cout<<"l,r:"<<l<<" "<<r<<endl;
		update(rt,l,r,cnt);
		return ;
	}
	int mid=(l+r)>>1;
	if(L<=mid)change(rt<<1,l,mid,L,R);
	if(mid+1<=R)change(rt<<1|1,mid+1,r,L,R);
	return ;
}
int lastans,ans;
double ansy;
void ask(int rt,int l,int r,int d){
	int mid=(l+r)>>1;
	double sum=clac(p[rt],d);
	if(sum-ansy>eps){
		ansy=sum;
		ans=p[rt];
	}
	if(abs(sum-ansy)<eps&&p[rt]<ans){
		ans=p[rt];
		ansy=sum;
	}
	if(l==r){
		lastans=ans;
		cout<<lastans<<endl;
		ansy=0;ans=0;
		return ;
	}
	if(d<=mid)ask(rt<<1,l,mid,d);
	else ask(rt<<1|1,mid+1,r,d);
	return ;
}
#define mod 1000000000
int main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		int op,t;
		cin>>op;
		if(op==0){
			cin>>t;
			int x=(t+lastans-1)%39989+1;
			ask(1,1,39989,x);
		}
		else{
			cin>>e1.xx>>e1.yy>>e2.xx>>e2.yy;
			e1.xx=(e1.xx+lastans-1)%39989+1;
			e2.xx=(e2.xx+lastans-1)%39989+1;
			e1.yy=(e1.yy+lastans-1)%mod+1;
			e2.yy=(e2.yy+lastans-1)%mod+1; 
			if(e1.xx>e2.xx)swap(e1,e2);
			cnt++;
//			cout<<e1.xx<<" "<<e1.yy<<" "<<e2.xx<<" "<<e2.yy<<endl;
			if(e1.xx==e2.xx){
				k[cnt]=0;
				b[cnt]=max(e1.yy,e2.yy);
			}
			else{
				k[cnt]=(1.0*(e2.yy-e1.yy))/(1.0*(e2.xx-e1.xx));
				b[cnt]=e1.yy-e1.xx*k[cnt];	
			}
//			cout<<k[cnt]<<" "<<b[cnt]<<endl;
			change(1,1,39989,e1.xx,e2.xx);
		}
	}
} 

标签:rt,线段,李超,笔记,yy,xx,e1,e2
From: https://www.cnblogs.com/shadom/p/17611942.html

相关文章

  • 笔记|聚类分析基础《Python数学实验与建模》
    参考图书为:《Python数学实验与建模》司守奎,孙玺菁定义将相似元素聚为一类通常分为Q型聚类(样本聚类)、R型聚类(指标聚类)。数据变换\(A=\begin{pmatrix}a_{11}&a_{12}&a_{13}&\cdots&a_{1p}\\a_{21}&a_{22}&a_{23}&\cdots&a_{2p}\\a_{31}&a_{32}&a_{33}&\cdots&a......
  • 笔记(一)---关于数据库连接对象释放
    publicvoidDispose(){Release();}publicvoidRelease(){try{if(connection!=null&&connection.State!=ConnectionState.Closed){......
  • linux循环语法错误笔记
     在freebsd上执行一个while循环,总是提示语法错误,查了许久资料,突然发现有人说到解释器问题,才焕然大悟,查看一下当前解释器:echo$SHELL果然,用的是csh,不是sh,也不是bash查看一下当前已安装解释器: cat/etc/shells那么就好说了,把命令写入脚本,然后用sh执行就行#!/bin/shwhile......
  • 新概念3册L7笔记(Mutilated ladies)
    课文如何写出优秀的解释说明类文章(exposition)1、语言生动活泼,充满趣味性。2、用词准确清晰,避免模棱两可。3、抽象说明与具体例证相结合。课文理解1)Hasiteverhappenedtoyou?固定搭配:happentodo2)Haveyoueverputyourtrousersinthewashingmachineandthenremem......
  • Springboot-Mybatis(idea)-自学笔记
    Spring-boot-Mybaties快速入门使用Mybatis查询所有用户数据准备工作(创建springboot工程,数据库表格user,实体类User)引入Mybatis的相关依赖,配置Mybatis(数据库连接信息)编写SQL语句(注解/XML)单元测试packagecom.example;importcom.example.mapper.UserMapper;impo......
  • 复习笔记|第九、十章 Linux文件系统《操作系统原理教程》
    参考教材:《操作系统原理教程(第4版)》刘美华翟岩龙著大纲问题回答(精简版)1.Ext2文件卷的布局?各部分的作用是什么?Ext2文件卷的布局◼Ext2把磁盘块分为组,每组包含存放在相邻磁道的数据块和索引节点。块组的大小相等并顺序安排。◼Ext2用“块组描述符”来描述这些块组本身的结......
  • 复习笔记|第十四章 Windows操作系统模型《操作系统原理教程》
    参考教材:《操作系统原理教程(第4版)》刘美华翟岩龙著大纲问题回答(精简版)1.Windows采用什么样的体系结构?从图中看出,系统划分为两种状态,核心态和用户态。粗线上方代表用户态进程,下方是核心态的操作系统服务。用户态的进程只能运行在受保护的地址空间。因此,四种类型的用户态进......
  • 复习笔记|第十五章 Windows进程和线程管理《操作系统原理教程》
    参考教材:《操作系统原理教程(第4版)》刘美华翟岩龙著大纲问题回答(精简版)1.管理进程和线程的数据结构:执行体进程块EPROCESS、执行体线程块ETHREAD、内核进程块KPROCESS、内核线程块KTHREAD。structEPROCESS{P285KPROCESSPCB;内核进程块ObjectTable;进程的句......
  • 复习笔记|第十六章 Windows存储器管理《操作系统原理教程》
    参考教材:《操作系统原理教程(第4版)》刘美华翟岩龙著大纲问题回答(精简版)1.两种数据结构:虚拟地址描述符VAD、区域对象,这两种结构各有什么作用?◆P304◼Windows系统采用一棵由虚拟地址描述符(VAD)构成的平衡二叉树来管理进程私有地址空间。一个进程的一组VAD结构构成一棵自平衡二......
  • 复习笔记|第十七章 Windows文件系统《操作系统原理教程》
    参考教材:《操作系统原理教程(第4版)》刘美华翟岩龙著大纲问题回答(精简版)1.Windows所支持的文件系统类型有哪些?❖支持FAT12、FAT16和FAT32文件系统。12、16和32分别为描述磁盘块簇地址使用的位数。NTFS.sys,使用64位的簇编号。❖现在主要使用NTFS(支持最大文件256TB)和FAT64(最大......