zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    关于如何实现NSNotificationCenter在不同的VC对象之间发送通知
    关于iOS如何实现一个单例
    C++中级-类模板
    C++中级-文件读写
    C++中级-多态
    C++中级-继承
    C++中级-friend关键字访问类中private
    C++中级-(静态成员和对象丶this指针丶常函数和对象、成员函数和对象)
    C++中级-(构造函数,拷贝构造函数,析构函数)
    C++中级-类的封装
  • 原文地址:https://www.cnblogs.com/LiGuanlin1124/p/10894688.html
Copyright © 2011-2022 走看看