bzoj3165 [Heoi2013]Segment

 题目描述:

bz

luogu

题解:

李超线段树模板题.

用一棵线段树去维护完全覆盖当前区间的所有线段中较优的一条,

怎么叫较优?意思是当出现两线段在区间中点相交时,我们记录一条就好,另一条向下传递更新子区间.

代码:

#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 100050;
const int M = 40050;
const int MAX = 40000;
const int MOD = 39989;
const int MDD = 1000000007;
const double eps = 1e-6;
template<typename T>
inline void read(T&x)
{
    T f = 1,c = 0;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){c=c*10+ch-'0';ch=getchar();}
    x = f*c;
}
struct Line
{
    double k,b;
    Line(){k=b=0;}
    Line(double k,double b):k(k),b(b){}
    Line(double x_1,double y_1,double x_2,double y_2)
    {
        if(x_1!=x_2)
        {
            k = (y_1-y_2)/(x_1-x_2);
            b = y_1 - k*x_1;
        }else    k=0,b=y_1;
    }
    double c(double x){return k*x+b;}
}e[N];
int n,ans;
struct lctree
{
    int nam[M<<2];
    void insert(int l,int r,int u,int ql,int qr,int k)
    {
        if(l==ql&&r==qr)
        {
            if(!nam[u]){nam[u]=k;return ;}
            double e0l = e[nam[u]].c(l),e0r = e[nam[u]].c(r);
            double e1l = e[k].c(l),e1r = e[k].c(r);
            if(e0l+eps<e1l&&e0r+eps<e1r){nam[u]=k;return ;}
            else if(e1l+eps<=e0l&&e1r+eps<=e0r)return ;
            int mid = (l+r)>>1;
            if(e[nam[u]].c(mid)+eps<e[k].c(mid))
            {
                insert(l,mid,u<<1,ql,mid,k);
                insert(mid+1,r,u<<1|1,mid+1,qr,k);
            }else
            {
                if(e0l+eps<e1l)insert(l,mid,u<<1,ql,mid,k);
                else insert(mid+1,r,u<<1|1,mid+1,qr,k);
            }
            return ;
        }
        int mid = (l+r)>>1;
        if(qr<=mid)insert(l,mid,u<<1,ql,qr,k);
        else if(ql>mid)insert(mid+1,r,u<<1|1,ql,qr,k);
        else insert(l,mid,u<<1,ql,mid,k),insert(mid+1,r,u<<1|1,mid+1,qr,k);
    }
    void query(int l,int r,int u,int qx)
    {
        if(nam[u])
            if(!ans||e[ans].c(qx)+eps<e[nam[u]].c(qx)||(ans>nam[u]&&fabs(e[nam[u]].c(qx)-e[ans].c(qx))<=eps))ans = nam[u];
        if(l==r)return ;
        int mid = (l+r)>>1;
        if(qx<=mid)query(l,mid,u<<1,qx);
        else query(mid+1,r,u<<1|1,qx);
    }
}tr;
int main()
{
//    freopen("tt.in","r",stdin);
    read(n);
    for(int op,x_1,y_1,x_2,y_2,k,tot=0,i=1;i<=n;i++)
    {
        read(op);
        if(!op)
        {
            read(k),k = (k+ans-1)%MOD+1;
            ans = 0;tr.query(0,MAX,1,k);
            printf("%d
",ans);
        }else
        {
            read(x_1),read(y_1),read(x_2),read(y_2);
            x_1 = (x_1%MOD+ans-1)%MOD+1;
            y_1 = (y_1%MDD+ans-1)%MDD+1;
            x_2 = (x_2%MOD+ans-1)%MOD+1;
            y_2 = (y_2%MDD+ans-1)%MDD+1;
            if(x_1>x_2)swap(x_1,x_2),swap(y_1,y_2);
            if(x_1==x_2)
            {
                if(y_1>y_2)y_2=y_1;
                else y_1=y_2;
            }
            e[++tot] = Line(x_1,y_1,x_2,y_2);
            tr.insert(0,MAX,1,x_1,x_2,tot);
        }
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/LiGuanlin1124/p/10894688.html