Lie segment tree (segment [HEOI2013] - Luo Gu T4097)

(Neng a very long time just to fool understand knowledge ...)

 

First, Li Chao segment tree

    Online maintaining a dynamic two-dimensional Cartesian coordinate system,

    Support insert a line,

    Ask the straight line X = X 0 all the line segments intersect, the maximum / minimum value of the intersection y

    (If multiple segments are eligible, the minimum number of line segments of the output number)

 

Luo Gu board title -Segment [HEOI2013] - Luo Gu T4097

 

Two, add operation

The core of the Lie segment tree is add operation

1. Japanese sentence l == r

It has come to a point

If you do not maintain the line before that point, direct current line maintenance

If the point had been maintained, the straight line (point) selected by the ordinate, the same ordinate, select a smaller number

2. If you do not happen to be placed in the interval

If, however mid, according to find about the relationship between mid

If over mid, split in two, respectively Find

3. If you happen to find a section

If this section does not maintain the line, the line maintenance

If there is,

(1) If there is a new midpoint, leaving new and old, the general left slightly larger (worse than the full-out), placed under the corresponding sub-interval.

(2) If the same value at the midpoint. Generally choose a new piduan decentralization (construction segment province). However, when a new number is small, and the right end point of the new segment is greater than or equal old ordinate, the right half of the old decentralized (at mid make certain that the acquired a new line segment, the number of which is smaller)

(3) If the old actor at the midpoint, empathy ...

 

//李超线段树
#include<cstdio>
#include<algorithm>
using namespace std;

inline int read()
{
    int sum = 0,p = 1;
    char ch = getchar();
    while(ch < '0' || ch > '9')
    {
        if(ch == '-')
            p = -1;
        ch = getchar();
    }
    while(CH> = ' 0 ' && CH <= ' . 9 ' ) 
    { 
        (SUM * = 10 ) + = CH - ' 0 ' ; 
        CH = getchar (); 
    } 
    return SUM * P; 
} 

#define MID ((L + R & lt) >>. 1)
 #define LSON L, MID, O <<. 1
 #define rson MID +. 1, R & lt, O. 1 << |. 1 const int MOD1 = 39989 , mod2 = 1E9, N = 50100 ;;
 int n-, ANS, lastans, id; // ANS actual answer, the answer lastans last query, id to the function Code No.

 
int   SX1 [N << 2 ], SX2 [N << 2 ], SY1 [N << 2 ], SY2 [N << 2 ], SUM [N << 2 ];
 BOOL VIS [N << 2 ];
 Double Tval; 

// O request node point value stored in the original function 
Double G ( int O, int X1, int Y1, int X2, int Y2) 
{ 
    IF (== X1 X2)
         return Y2;
     the else 
        return  1.0 * ( O - X2) * (Y1 - Y2) / (X1 - X2) + Y2; 
} 

//When a new function is added to modify operation of one straight line perpendicular to the x-axis 
void Change ( int x, int V, int TOT, int L, int R & lt, int O) 
{ 
    IF (L == R & lt) 
    { 
        IF (! VIS [O]) 
        { 
            SX1 [O] = SX2 [O] = L; 
            SY1 [O] = SY2 [O] = V; 
            SUM [O] = TOT; 
            VIS [O] = to true ; 
        } 
        the else 
        { 
            Double CNT =G (X, SX1 [O], SY1 [O], SX2 [O], SY2 [O]);
             IF (CNT> V || (CNT && == V TOT < SUM [O])) 
            { 
                SX1 [O ] = SX2 [O] = L; 
                SY1 [O] = SY2 [O] = V; 
                SUM [O] = TOT; 
            } 
        } 
        return ; 
    } 
    IF (MID> = X) 
        Change (X, V, TOT, LSON) ; 
    the else 
        Change (X, V, TOT, rson); 
} 

// find the intersection of the two functions 
Double Inter ( Double X1, Double Y1, Double X2,double y2,double x3,double y3,double x4,double y4)
{
    double a,b,c,d,g,h,f,t,s;
    a = x2 - x1;
    b = x3 - x4;
    c = y2 - y1;
    d = y3 - y4;
    g = x3 - x1;
    h = y3 - y1;
    f = a *d - b * c;
    t = (d * g - b * h)/f;
    return x1 +t * (x2 - x1);
}

void update(int ql,int qr,int x1,int y1,int x2,int y2,int tot,int l,int r,int o)
{
    if(ql <= l && r <= qr)
    {
        if(!vis[o])
        {
            sx1[o] = x1,sy1[o] = y1,sx2[o] = x2,sy2[o] = y2;
            sum[o] = tot;
            vis[o] = true;
        }
        else
        {
            double f1,f2,f3,f4;
            f1 = G(l,x1,y1,x2,y2);
            f2 = G(l,sx1[o],sy1[o],sx2[o],sy2[o]);
            f3 = G(r,x1,y1,x2,y2);
            f4 = G(r,sx1[o],sy1[o],sx2[o],sy2[o]);
            if(f1 <= f2 && f3 <= f4)
                return;
            else if(f1 >= f2 && f3 >= f4)
            {
                sx1[o] = x1,sy1[o] = y1,sx2[o] = x2,sy2[o] = y2;
                sum[o] = tot;
            }
            else
            {
                double spot = Inter(x1,y1,x2,y2,sx1[o],sy1[o],sx2[o],sy2[o]);
                if(f1 >= f2)
                {
                    if(spot <= mid)
                        update(ql,qr,x1,y1,x2,y2,tot,lson);
                    else
                    {
                        update(ql,qr,sx1[o],sy1[o],sx2[o],sy2[o],sum[o],rson);
                        sx1[o] = x1,sy1[o] = y1,sx2[o] = x2,sy2[o] = y2;
                        sum[o] = tot;
                    }
                }
                else
                {
                    if(spot > mid)
                        update(ql,qr,x1,y1,x2,y2,tot,rson);
                    else
                    {
                        update(ql,qr,sx1[o],sy1[o],sx2[o],sy2[o],sum[o],lson);
                        sx1[o] = x1,sy1[o] = y1,sx2[o] = x2,sy2[o] = y2;
                        sum[o] = tot;
                    }
                }
            }
        }
        return;
    }
    if(ql <= mid)
        update(ql,qr,x1,y1,x2,y2,tot,lson);
    if(qr > mid)
        update(ql,qr,x1,y1,x2,y2,tot,rson);
}

void query(int x,int l,int r,int o)
{
    if(vis[o])
    {
        double cnt = G(x,sx1[o],sy1[o],sx2[o],sy2[o]);
        if(cnt > tval || cnt == tval && sum[o] < ans)
        {
            tval = cnt;
            ans = sum[o];
        }
    }
    if(l == r)
        return;
    if(mid >= x)
        query(x,lson);
    else
        query(x,rson);
}

int main()
{
    n = read();
    while(n--)
    {
        int opt = read();
        if(!opt)
        {
            int x = read();
            x = (x + lastans - 1)%mod1 + 1;
            ans = 0;
            tval = 0;
            query(x,1,50000,1);
            printf("%d\n",ans);
            lastans = ans;
        }
        else
        {
            int x1 = read(),y1 = read(),x2 = read(),y2 = read();
            x1 = (x1 + lastans - 1)%mod1 + 1;
            y1 = (y1 + lastans - 1)%mod2 + 1;
            x2 = (x2 + lastans - 1)%mod1 + 1;
            y2 = (y2 + lastans - 1)%mod2 + 1;
            if(x1 > x2)
            {
                swap(x1,x2);
                swap(y1,y2);
            }
            if(x1 == x2)
                change(x1,max(y1,y2),++id,1,50000,1);
            else
                update(x1,x2,x1,y1,x2,y2,++id,1,50000,1);
        }
    }
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/darlingroot/p/11248951.html