zoukankan      html  css  js  c++  java
  • 【学习笔记】李超线段树

    李超线段树

    动态维护一个平面直角坐标系,支持在中间插入一条线段,支持询问与 (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

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

  • 相关阅读:
    java代码--Date类获取当前时间-格式化输出
    Eclipse快速生成do while if 等方法
    java不同包中protected修饰的属性和方法调用方法
    java中如果删除导入的jar包,工程出现叹号解决方案
    Best Reward HDU 3613(回文子串Manacher)
    Teacher YYF
    Period II
    How many
    String Problem
    Corporate Identity
  • 原文地址:https://www.cnblogs.com/yspm/p/12313319.html
Copyright © 2011-2022 走看看