(neng了好久好久才糊弄懂得知识点...)

一、李超线段树

    在线动态维护一个二维平面直角坐标系,

    支持插入一条线段,

    询问与直线x = x0相交的所有线段中,交点y的最大/小值

    (若有多条线段符合条件,输出编号最小的线段的编号)

洛谷板子题-Segment[HEOI2013]-洛谷T4097

二、add操作

整个李超线段树的核心就是add操作

1.特判 l == r

已经到了一个点

如果该点之前没有维护线段,直接维护现在的线段

如果该点已经维护过,选择纵坐标靠上的直线(点),纵坐标相同,选择编号较小的

2.如果没有恰好放在区间里

如果不过mid,根据与mid关系左右查找

如果过mid,劈两半分别查找

3.如果找到了恰好的区间

如果该区间没有维护线段,维护该线段

如果有,

(1).如果中点处新的有,留下新的,把旧的中,稍大的一般留下(全劣则淘汰),下放到对应的子区间。

(2).如果中点处值相同。一般情况选择新的劈断的下放(省的建线段)。但是当新的编号较小,并且新的线段的右端点的纵坐标大于等于旧的,将旧的右半部分下放(使mid处一定取得的使新的线段,也就是编号较小的)

(3).如果中点处旧的优,同理...

//李超线段树
#include<cstdio>
#include<algorithm>
using namespace std; inline int read()
{
int sum = ,p = ;
char ch = getchar();
while(ch < '' || ch > '')
{
if(ch == '-')
p = -;
ch = getchar();
}
while(ch >= '' && ch <= '')
{
(sum *= ) += ch - '';
ch = getchar();
}
return sum * p;
} #define mid ((l + r)>>1)
#define lson l,mid,o<<1
#define rson mid + 1,r,o<<1|1 const int mod1 = ,mod2 = 1e9,N = ;;
int n,ans,lastans,id;//ans实际答案,lastans上次查询的答案,id给函数编的号
int sx1[N << ],sx2[N << ],sy1[N << ],sy2[N << ],sum[N << ];
bool vis[N << ];
double tval; //求节点储存的原函数的o点的值
double G(int o,int x1,int y1,int x2,int y2)
{
if(x1 == x2)
return y2;
else
return 1.0 *(o - x2) *(y1 - y2)/(x1 - x2) +y2;
} //当新加入的函数是一条垂直于x轴的直线时 的修改操作
void change(int x,int v,int tot,int l,int r,int o)
{
if(l == r)
{
if(!vis[o])
{
sx1[o] = sx2[o] = l;
sy1[o] = sy2[o] = v;
sum[o] = tot;
vis[o] = true;
}
else
{
double cnt = G(x,sx1[o],sy1[o],sx2[o],sy2[o]);
if(cnt > v || (cnt == v && tot < sum[o]))
{
sx1[o] = sx2[o] = l;
sy1[o] = sy2[o] = v;
sum[o] = tot;
}
}
return;
}
if(mid >= x)
change(x,v,tot,lson);
else
change(x,v,tot,rson);
} //求两个函数的交点
double Inter(double x1,double y1,double x2,double y2,double x3,double y3,double x4,double y4)
{
double a,b,c,d,g,h,f,t,s;
a = x2 - x1;
b = x3 - x4;
c = y2 - y1;
d = y3 - y4;
g = x3 - x1;
h = y3 - y1;
f = a *d - b * c;
t = (d * g - b * h)/f;
return x1 +t * (x2 - x1);
} void update(int ql,int qr,int x1,int y1,int x2,int y2,int tot,int l,int r,int o)
{
if(ql <= l && r <= qr)
{
if(!vis[o])
{
sx1[o] = x1,sy1[o] = y1,sx2[o] = x2,sy2[o] = y2;
sum[o] = tot;
vis[o] = true;
}
else
{
double f1,f2,f3,f4;
f1 = G(l,x1,y1,x2,y2);
f2 = G(l,sx1[o],sy1[o],sx2[o],sy2[o]);
f3 = G(r,x1,y1,x2,y2);
f4 = G(r,sx1[o],sy1[o],sx2[o],sy2[o]);
if(f1 <= f2 && f3 <= f4)
return;
else if(f1 >= f2 && f3 >= f4)
{
sx1[o] = x1,sy1[o] = y1,sx2[o] = x2,sy2[o] = y2;
sum[o] = tot;
}
else
{
double spot = Inter(x1,y1,x2,y2,sx1[o],sy1[o],sx2[o],sy2[o]);
if(f1 >= f2)
{
if(spot <= mid)
update(ql,qr,x1,y1,x2,y2,tot,lson);
else
{
update(ql,qr,sx1[o],sy1[o],sx2[o],sy2[o],sum[o],rson);
sx1[o] = x1,sy1[o] = y1,sx2[o] = x2,sy2[o] = y2;
sum[o] = tot;
}
}
else
{
if(spot > mid)
update(ql,qr,x1,y1,x2,y2,tot,rson);
else
{
update(ql,qr,sx1[o],sy1[o],sx2[o],sy2[o],sum[o],lson);
sx1[o] = x1,sy1[o] = y1,sx2[o] = x2,sy2[o] = y2;
sum[o] = tot;
}
}
}
}
return;
}
if(ql <= mid)
update(ql,qr,x1,y1,x2,y2,tot,lson);
if(qr > mid)
update(ql,qr,x1,y1,x2,y2,tot,rson);
} void query(int x,int l,int r,int o)
{
if(vis[o])
{
double cnt = G(x,sx1[o],sy1[o],sx2[o],sy2[o]);
if(cnt > tval || cnt == tval && sum[o] < ans)
{
tval = cnt;
ans = sum[o];
}
}
if(l == r)
return;
if(mid >= x)
query(x,lson);
else
query(x,rson);
} int main()
{
n = read();
while(n--)
{
int opt = read();
if(!opt)
{
int x = read();
x = (x + lastans - )%mod1 + ;
ans = ;
tval = ;
query(x,,,);
printf("%d\n",ans);
lastans = ans;
}
else
{
int x1 = read(),y1 = read(),x2 = read(),y2 = read();
x1 = (x1 + lastans - )%mod1 + ;
y1 = (y1 + lastans - )%mod2 + ;
x2 = (x2 + lastans - )%mod1 + ;
y2 = (y2 + lastans - )%mod2 + ;
if(x1 > x2)
{
swap(x1,x2);
swap(y1,y2);
}
if(x1 == x2)
change(x1,max(y1,y2),++id,,,);
else
update(x1,x2,x1,y1,x2,y2,++id,,,);
}
}
return ;
}

李超线段树(segment[HEOI2013]-洛谷T4097)的更多相关文章

  1. 2018.07.23 洛谷P4097 [HEOI2013]Segment(李超线段树)

    传送门 给出一个二维平面,给出若干根线段,求出x" role="presentation" style="position: relative;"&g ...

  2. 洛谷P4097 [HEOI2013]Segment(李超线段树)

    题面 传送门 题解 调得咱自闭了-- 不难发现这就是个李超线段树,不过因为这里加入的是线段而不是直线,所以得把线段在线段树上对应区间内拆开之后再执行李超线段树的操作,那么复杂度就是\(O(n\log^ ...

  3. 【洛谷P4097】Segment 李超线段树

    题目大意:维护一个二维平面,给定若干条线段,支持询问任意整数横坐标处对应的纵坐标最靠上的线段的 id,相同高度取 id 值较小的,强制在线. 题解:初步学习了李超线段树.李超线段树的核心思想在于通过标 ...

  4. 【BZOJ3165】[HEOI2013]Segment(李超线段树)

    [BZOJ3165][HEOI2013]Segment(李超线段树) 题面 BZOJ 洛谷 题解 似乎还是模板题QwQ #include<iostream> #include<cst ...

  5. Luogu P4097 [HEOI2013]Segment 李超线段树

    题目链接 \(Click\) \(Here\) 李超线段树的模板.但是因为我实在太\(Naive\)了,想象不到实现方法. 看代码就能懂的东西,放在这里用于复习. #include <bits/ ...

  6. 洛谷P4069 [SDOI2016]游戏(李超线段树)

    题意 题目链接 Sol 这题细节好多啊qwq..稍不留神写出一个小bug就要调1h+.. 思路就不多说了,把询问区间拆成两段就是李超线段树板子题了. 关于dis的问题可以直接维护. // luogu- ...

  7. BZOJ3165: [Heoi2013]Segment(李超线段树)

    题意 题目链接 Sol 李超线段树板子题.具体原理就不讲了. 一开始自己yy着写差点写自闭都快把叉积搬出来了... 后来看了下litble的写法才发现原来可以写的这么清晰简洁Orz #include& ...

  8. 洛谷P4069 [SDOI2016]游戏(李超线段树)

    题面 传送门 题解 如果我们把路径拆成两段,那么这个路径加可以看成是一个一次函数 具体来说,设\(dis_u\)表示节点\(u\)到根节点的距离,那么\((x,lca)\)这条路径上每个节点的权值就会 ...

  9. 洛谷P4254 [JSOI2008]Blue Mary开公司(李超线段树)

    题面 传送门 题解 李超线段树板子 具体可以看这里 //minamoto #include<bits/stdc++.h> #define R register #define fp(i,a ...

随机推荐

  1. 2.restEasy中@PathParam和@QueryParam的区别

    例如代码: @GET @Path("/{id}") @Produces(MediaType.APPLICATION_JSON) public T query(@PathParam( ...

  2. 洛谷P1071 潜伏者

    https://www.luogu.org/problem/P1071 #include<bits/stdc++.h> using namespace std; map<char,c ...

  3. day22 定时任务

    检查软件是否安装 cronie [root@oldboyedu ~]# rpm -qa cronie cronie-1.4.11-19.el7.x86_64 [root@oldboyedu ~]# r ...

  4. 素问 - IC移仓换月

    摘自<小韭的学习圈> Q 股指期货的合约什么时候换月比较合适? 今天是1908股指期货的交割日,我是这么操作的:我在10:30分把IH1908以2827元卖出,然后马上以2805.8元买入 ...

  5. c#中的位运算

    &与  全为1才是1 |或  全为0才是0 !非  两边相同时为1,不同时为0 ~取反  0变1,1变0,包括符号位 >>右移 溢出舍掉,正数补0,负数补1,移动n位:原数 / 2 ...

  6. python 自动化实现定时发送html报告到邮箱

    # coding =utf-8 import os import unittest import time import datetime import smtplib from email.mime ...

  7. 我写的UI自动化框架

    ---------------------------------------------------------------------------------------------------- ...

  8. C++-hihoCode-1105/1109-[STL][堆][prime]

    #include <set> #include <map> #include <cmath> #include <queue> #include < ...

  9. mysql 查询时间戳格式化 和thinkphp查询时间戳转换

    我在网上看了好多写的,都差不多,甚至好多都是一个人写的被别人转载啥的,哎 我写一个比较简单的 1.mysql语句 格式化时间戳 select id,name,FROM_UNIXTIME(time,'% ...

  10. C. Grid game 思维+问题转化

    C. Grid game 思维+问题转化 题意 每当有一行或者一列方格的时候,都可以消气这一行或者这一列,一共有两种形状的方块,一种是横的两个,一种是竖着的两个,按时间顺序放在4*4的格子里面,问怎么 ...