• 【学习笔记】李超线段树


    李超线段树

    动态维护一个平面直角坐标系,支持在中间插入一条线段,支持询问与 (x=x_0) 这条直线相交的所有线段中,交点的 (y) 轴坐标的最大(小)值。

    想到把一条线段拆成 (x) 值为整数的点,这里 (y) 值开 (double) 就没有问题了

    主要是考虑怎么插入一条直线,假设它当前处理到了某个区间:

    • 区间没有记录最长的线段:那么直接把这个区间记录的线段修改为这条线段

    • 当前线段在这个区间内已经被这个区间内的最长线段为覆盖: 直接返回。

    • 完全覆盖了之前记录的线段: 区间修改

    • 和已经记录的直线有交:判断哪根线段覆盖的区域较长,把这个区间记录的值给修改一下,然后把短的那一半丢下去递归。

    查询还是很水的

    Code Part

    inline void insert(int p,int l,int r,int x1,int x2,node now)
    	{
    		if(l>=x1&&r<=x2)
    		{
    			int mid=(l+r)>>1;
    			if(calc(t[p],mid)<calc(now,mid)||(!t[p].num)) swap(t[p],now);
    			double jd=1.0*(t[p].b-now.b)/(now.k-t[p].k);
    			if(l==r||t[p].k==now.k||jd<1.0*l||jd>1.0*r||(!now.num)) return ;
    			if(now.k<t[p].k) insert(p<<1,l,mid,x1,x2,now);
    			else insert(p<<1|1,mid+1,r,x1,x2,now);
    		}
    		else
    		{
    			int mid=(l+r)>>1;
    			if(x1<=mid) insert(p<<1,l,mid,x1,x2,now);
    			if(x2>mid) insert(p<<1|1,mid+1,r,x1,x2,now);
    		}return ;
    	}
     	inline node query(int p,int l,int r,int x)
    	{
    		if(l==r) return t[p];
    		int mid=(l+r)>>1; node k;
    		if(x<=mid) k=query(p<<1,l,mid,x);
    		else k=query(p<<1|1,mid+1,r,x);
    		return ((!k.num)||calc(k,x)<calc(t[p],x))?t[p]:k;
    	}
    

    例题

    HEOI2013 Segment

    确实是模板题,甚至上面的码就是粘的那里的

  • 相关阅读:
    Oracle 手工创建awr快照,获取报告
    Oracle块修改跟踪功能
    Oracle 反向索引(反转建索引) 理解
    oracle聚簇表的理解 (转自:https://blog.csdn.net/gumengkai/article/details/51009345 )
    Fix the iOS code signing issue when using Jenkins
    ios系统crash文件分析
    python版本管理
    python requirements.txt
    android makefile protoc路径添加
    初识tflite源码
  • 原文地址:https://www.cnblogs.com/yspm/p/12313319.html
Copyright © 2020-2023  润新知