李超线段树

现在要求你在线动态维护一个二维平面直角坐标系,支持插入一条线段,询问与直线x=x0相交的所有线段中交点y的最大/最小值

–李超线段树解决的问题

现在我们只考虑询问最大,事实上最小是同理的

线段树维护覆盖这个区间的”最优势线段”,”最优势线段”指覆盖此区间且暴露最多的线段

比如对于区间A红色为”最优势线段”

可以证明对于一个位置的询问,答案一定在所有包含这个位置的区间的”最优势线段”里

维护的话,考虑当前加入线段与原”最优势线段”的关系

还没有”最优势线段” -> 直接改

新的把旧的盖住了 -> 直接改

旧的把新的盖住了 -> 直接返回

有交点 -> 比较谁更优势,把不优势的下放到交点所在儿子区间上

询问的话自底向上把每个经过的区间的答案取最大值即可

一条线段会没分配到O(logn)个区间上,每个区间至多下放O(logn)次

修改操作复杂度O(log^2n),查询O(logn)

例题
P4254 [JSOI2008]Blue Mary开公司

#include<cstdio>
#include <iostream>
using namespace std;
const int M=500003;
double b[M*2],k[M*2];int val[M*4],cnt,n;
double d[]={0,1e-1,1e-2,1e-3,1e-4,1e-5,1e-6,1e-7,1e-8,1e-9,1e-10};
double read(){
    int x=0,w=1,now=0,f=0;double xs=0;char ch=0;
    while(ch<'0'||ch>'9'){if(ch=='-') w=-1; ch=getchar();}
    while(ch>='0'&&ch<='9'||(ch=='.')){
        if(ch=='.'){f=1;ch=getchar();continue; } 
        if(f) xs+=(((ch-'0')*d[++now]));
        else x=((x<<3)+(x<<1)+ch-'0');ch=getchar();
    }
    xs+=(double)x;
    return xs*w;
}
bool check(int x,int y,int t){
    return (b[x]+k[x]*(t-1))>(b[y]+k[y]*(t-1));
} 
void insert(int o,int l,int r,int id){
    if(l>=r){
        if(check(id,val[o],l)) val[o]=id;return ;
    }int mid=(l+r)>>1;
    if(k[id]>k[val[o]]){
        if(check(id,val[o],mid)) insert(o<<1,l,mid,val[o]),val[o]=id;
        else insert(o<<1|1,mid+1,r,id);
    }
    else {
        if(check(id,val[o],mid)) insert(o<<1|1,mid+1,r,val[o]),val[o]=id;
        else insert(o<<1,l,mid,id);
    }
}
double ask(int o,int l,int r,int id){
    if(l>=r) return b[id]+k[id]*(id-1);
    int mid=(l+r)>>1;
    double ans=b[val[o]]+k[val[o]]*(id-1);
    if(id>mid) return max(ans,ask(o<<1|1,mid+1,r,id));
    else return max(ans,ask(o<<1,l,mid,id));
}
int main(){
    scanf("%d",&n);
    for(int i=1,d;i<=n;i++){char s[20];
        scanf("%s",s);
        if(s[0]=='P'){cnt++;
            b[cnt]=read(),k[cnt]=read();
            insert(1,1,M,cnt);
        }
        else{
            scanf("%d",&d);
            printf("%d\n",(int)ask(1,1,M,d)/100);
        }
    }
}

由于蒟蒻没搞懂。。
暂时只有这一个题。。。。
上面的还是转载的
转自http://blog.csdn.net/flere825/article/details/76283734

有例题BZOJ3165 BZOJ1568 BZOJ3938BZOJ4515

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值