ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

李超线段树

2022-05-01 11:34:57  阅读:150  来源: 互联网

标签:sx int 线段 db 李超 IO define


解决多线段单点最值问题。

模板题

浅略的说一下。

每个区间存储位于当前区间中的值最大的线段。每次插入新线段,如果当前区间没有存储线段,就直接插在这里,否则分类讨论一下,如果某一个子区间的最优线段必定是当前线段,这个子区间就不用处理了。而对于另一个有不确定因素的,我们把当前的不优线段下传即可。具体实现看代码,本质上是标记永久化,所以查询的时候直接对于每个点都更新一下答案就好。

#include<bits/stdc++.h>
#define ll long long
#define db double 
#define filein(a) freopen(#a".in","r",stdin)
#define fileot(a) freopen(#a".out","w",stdout)
#define Better_IO true
namespace IO{
    #if Better_IO
        char buf[(1<<20)+3],*p1(buf),*p2(buf);
        const int lim=1<<20;
        inline char gc(){
            if(p1==p2) p2=(p1=buf)+fread(buf,1,lim,stdin);
            return p1==p2?EOF:*p1++;
        }
        #define pc putchar
    #else
        #define gc getchar
        #define pc putchar
    #endif
    inline bool blank(char c){
        return c=='\t' or c=='\n' or c=='\r' or c==' ' or c==EOF;
    }
    inline void gs(char *s){
        char ch=gc();
        while(blank(ch) ) ch=gc();
        while(!blank(ch) ) {*s++=ch;ch=gc();}
        *s=0;
    }
    inline void ps(char *s){
        while(*s!=0) {pc(*s++);}
    }
    template<class T>
    inline void read(T &s){
        s=0;char ch=gc();bool f=0;
        while(ch<'0'||'9'<ch) {if(ch=='-') f=1;ch=gc();}
        while('0'<=ch&&ch<='9') {s=s*10+(ch^48);ch=gc();}
        if(ch=='.'){
            db p=0.1;ch=gc();
            while('0'<=ch&&ch<='9') {s=s+p*(ch^48);ch=gc();p*=0.1;}
        }
        s=f?-s:s;
    }
    template<class T,class ...A>
    inline void read(T &s,A &...a){
        read(s);read(a...);
    }
};
using IO::gs;
using IO::ps;
using IO::read;
using IO::gc;
const int N=1e5+3;
int n;
const db inf=1e9;
int tot;
struct line{
    db k,b;
}p[N];
inline line change(int sx,int sy,int fx,int fy){
    db k,b;
    if(sx==fx){
        k=0;
        b=std::max(sy,fy);
    }else{
        k=(db)(fy-sy)/(db)(fx-sx);
        b=sy-(db)k*sx;
    }
    return (line){k,b};
}
#define pr std::pair<db,int>
inline pr max(pr x,pr y){
    if(x.first<y.first) return y;
    else if(x.first>y.first) return x;
    return x.second<y.second?x:y;
} 
inline db calc(int id,int x){
    return (p[id].k*x+p[id].b);
}
const int N2=39989+3;
struct SegTree{
    #define lc(x) (x<<1)
    #define rc(x) (x<<1|1)
    struct node{
        int l,r,mid;
        int id;
    }t[N2<<2];
    inline void build(int x,int l,int r){
        t[x].l=l;t[x].r=r;t[x].mid=(l+r)>>1;
        t[x].id=0;
        if(l==r){
            return;
        }
        build(lc(x),l,t[x].mid);
        build(rc(x),t[x].mid+1,r);
    }
    inline void modify(int x,int l,int r,int id){
        if(t[x].l>r or t[x].r<l) return;
        db val1=calc(t[x].id,t[x].mid),val2=calc(id,t[x].mid);
        if(l<=t[x].l and t[x].r<=r){
            if(!t[x].id){
                t[x].id=id;
                return;
            }
            if(t[x].l==t[x].r){
                if(val1<val2) t[x].id=id;
                else if(val1==val2) t[x].id=std::min(id,t[x].id);
                return;
            }
            if(p[t[x].id].k<p[id].k){
                if(val1<val2){
                    modify(lc(x),l,r,t[x].id);
                }else{
                    modify(rc(x),l,r,id);
                }
            }else if(p[t[x].id].k>p[id].k){
                if(val1<val2){
                    modify(rc(x),l,r,t[x].id);
                }else{
                    modify(lc(x),l,r,id);
                }
            }
            if(val1<val2) t[x].id=id;
            else if(val1==val2) t[x].id=std::min(id,t[x].id);
            return;
        }
        modify(lc(x),l,r,id);
        modify(rc(x),l,r,id);
    }
    inline pr query(int x,int k){
        db res=calc(t[x].id,k);
        pr ans={res,t[x].id};
        if(t[x].l==t[x].r) return ans;
        if(k<=t[x].mid) ans=max(ans,query(lc(x),k) );
        if(t[x].mid+1<=k) ans=max(ans,query(rc(x),k) );
        return ans;
    }
    #undef lc
    #undef rc
}t;
int la;
int main(){
    filein(a);fileot(a);
    read(n);
    p[0]={-1e9,-1e9};
    t.build(1,1,39989);
    for(int i=1;i<=n;++i){
        int op;
        read(op);
        if(op==0){
            int x;
            read(x);
            x=(x+la-1)%39989+1;
            printf("%d\n",la=t.query(1,x).second);
        }
        if(op==1){
            int sx,sy,fx,fy;
            read(sx,sy,fx,fy);
            sx=(sx+la-1)%39989+1;
            sy=(sy+la-1)%(int)1e9+1;
            fx=(fx+la-1)%39989+1;
            fy=(fy+la-1)%(int)1e9+1;
            if(sx>fx){
                std::swap(sx,fx);
                std::swap(sy,fy);
            }
            p[++tot]=change(sx,sy,fx,fy);
            t.modify(1,sx,fx,tot);
        }
    }
    return 0;
}

标签:sx,int,线段,db,李超,IO,define
来源: https://www.cnblogs.com/cbdsopa/p/16212416.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有