zoukankan      html  css  js  c++  java
  • BZOJ3165:[HEOI2013]Segment

    浅谈标记永久化:https://www.cnblogs.com/AKMer/p/10137227.html

    题目传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=3165

    跟这题一样:https://www.cnblogs.com/AKMer/p/10138264.html

    不过需要线段完全覆盖当前区间才能递归去替换标记。

    时间复杂度:(O(nlog^2n))

    空间复杂度:(O(n))

    代码如下:

    #include <cstdio>
    #include <algorithm>
    using namespace std;
    
    const int maxn=1e5+5,maxlen=4e4+4,pps=39989;
    
    int n,lstans,cnt;
    double b[maxn],k[maxn];
    
    inline int read() {
        int x=0,f=1;char ch=getchar();
        for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
        for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
        return x*f;
    }
    
    inline double calc(int id,int x) {
        return k[id]*x+b[id];
    }
    
    inline bool check(int id1,int id2,int x) {
        double A=k[id1]*x+b[id1],B=k[id2]*x+b[id2];
        if(A!=B)return A<B;
        return id1>id2;
    }
    
    struct segment_tree {
        int tag[maxlen<<2];
    
        int query(int p,int l,int r,int pos) {
            if(l==r)return tag[p];
            int mid=(l+r)>>1;int res;
            if(pos<=mid)res=query(p<<1,l,mid,pos);
            else res=query(p<<1|1,mid+1,r,pos);
            if(check(tag[p],res,pos))return res;
            return tag[p];
        }
    
        void change_tag(int p,int l,int r,int id) {
            if(l==r) {if(check(tag[p],id,l))tag[p]=id;return;}
            int mid=(l+r)>>1;
            if(k[id]>k[tag[p]]) {
                if(check(tag[p],id,mid))change_tag(p<<1,l,mid,tag[p]),tag[p]=id;
                else change_tag(p<<1|1,mid+1,r,id);
            }
            else {
                if(check(tag[p],id,mid))change_tag(p<<1|1,mid+1,r,tag[p]),tag[p]=id;
                else change_tag(p<<1,l,mid,id);
            }
        }
    
        void change(int p,int l,int r,int L,int R) {
            if(L<=l&&r<=R) {change_tag(p,l,r,cnt);return;}
            int mid=(l+r)>>1;
            if(L<=mid)change(p<<1,l,mid,L,R);
            if(R>mid)change(p<<1|1,mid+1,r,L,R);
        }
    }T;
    
    inline int fakein(int p) {
        int x=read();
        return (x+lstans-1)%p+1;
    }
    
    inline void make(int id,int x0,int y0,int x1,int y1) {
        if(x0==x1)k[id]=0,b[id]=max(y1,y0);
        else {
            k[id]=1.0*(y1-y0)/(x1-x0);
            b[id]=1.0*y0-k[id]*x0;
        }
    }
    
    int main() {
        n=read();
        for(int i=1;i<=n;i++) {
            int opt=read();
            if(opt==0) {
                int k=fakein(pps);
                lstans=T.query(1,1,pps,k);
                printf("%d
    ",lstans);
            }
            else {
                int x0=fakein(pps),y0=fakein(1e9),x1=fakein(pps),y1=fakein(1e9);
                if(x0>x1)swap(x1,x0),swap(y0,y1);
                make(++cnt,x0,y0,x1,y1);
                T.change(1,1,pps,x0,x1);
            }
        }
        return 0;
    }
    
  • 相关阅读:
    前端-JavaScript
    前端-HTML
    Python源程序(.py)转换为可执行文件(.exe)
    进程
    算法之动态规划问题
    算法之斐波那契数列
    贪心算法找零问题
    算法之迷宫问题
    数据结构相关知识
    常用排序算法
  • 原文地址:https://www.cnblogs.com/AKMer/p/10150676.html
Copyright © 2011-2022 走看看