(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;
}