题目链接
有N次操作,强制在线,每次要么查询时候的与已有线段的最大交点值的对应线段序号,要么就是插入一个线段。
于是,就是一个很明显的一个李超线段树了,用永久化标记来进行操作,当插入对应区间的时候,利用它和已有的覆盖线段来进行比较,我们可以知道它们的关系。
#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <bitset>
#include <unordered_map>
#include <unordered_set>
#define lowbit(x) ( x&(-x) )
#define pi 3.141592653589793
#define e 2.718281828459045
#define INF 0x3f3f3f3f
#define HalF (l + r)>>1
#define lsn rt<<1
#define rsn rt<<1|1
#define Lson lsn, l, mid
#define Rson rsn, mid+1, r
#define QL Lson, ql, qr
#define QR Rson, ql, qr
#define myself rt, l, r
using namespace std;
typedef unsigned long long ull;
typedef unsigned int uit;
typedef long long ll;
const int maxN = 4e4 + 10;
int N;
const int mod = 39989, MOD = 1e9;
pair<double, double> line[100005];
int t[maxN << 2] = {0};
const int UL = 0, UR = 4e4;
double H[maxN] = {0};
int hid[maxN] = {0};
inline void update(int rt, int l, int r, int xl, int xr, int v)
{
int mid = HalF;
int u = t[rt];
if(xl <= l && xr >= r)
{
if(u)
{
double old = line[u].first * mid + line[u].second;
double now = line[v].first * mid + line[v].second;
if(line[v].first > line[u].first)
{
if(old < now)
{
t[rt] = v;
if(l ^ r) update(Lson, xl, xr, u);
}
else
{
if(l ^ r) update(Rson, xl, xr, v);
}
}
else if(line[v].first < line[u].first)
{
if(old >= now)
{
if(l ^ r) update(Lson, xl, xr, v);
}
else
{
t[rt] = v;
if(l ^ r) update(Rson, xl, xr, u);
}
}
else
{
if(line[u].second < line[v].first)
{
t[rt] = v;
}
}
}
else
{
t[rt] = v;
}
return;
}
if(l == r) return;
if(xr <= mid) update(Lson, xl, xr, v);
else if(xl > mid) update(Rson, xl, xr, v);
else { update(Lson, xl, xr, v); update(Rson, xl, xr, v); }
}
double ans = 0;
int ans_id = 0;
void query(int rt, int l, int r, double qx)
{
int u = t[rt];
if(u)
{
double y = line[u].first * qx + line[u].second;
if(y > ans)
{
ans = y;
ans_id = u;
}
else if(y == ans)
{
ans_id = min(ans_id, u);
}
}
if(l == r) return;
int mid = HalF;
if(qx <= mid) query(Lson, qx);
else query(Rson, qx);
}
inline void ID(int &x) { x = (x + ans_id - 1) % mod + 1; }
inline void CD(int &y) { y = (y + ans_id - 1) % MOD + 1; }
int main()
{
scanf("%d", &N);
int cnt = 0;
for(int i=1, op, x[3], y[3]; i<=N; i++)
{
scanf("%d", &op);
if(!op)
{
scanf("%d", &x[0]);
ID(x[0]);
ans = -1; ans_id = 0;
query(1, UL, UR, x[0]);
if(hid[x[0]] && ans < H[x[0]])
{
ans = H[x[0]];
ans_id = hid[x[0]];
}
printf("%d\n", ans_id);
}
else
{
scanf("%d%d%d%d", &x[0], &y[0], &x[1], &y[1]);
ID(x[0]); CD(y[0]); ID(x[1]); CD(y[1]);
if(x[0] == x[1])
{
if(y[0] > y[1]) swap(y[0], y[1]);
if(H[x[0]] < y[1])
{
H[x[0]] = y[1];
hid[x[0]] = ++cnt;
continue;
}
}
if(x[0] > x[1])
{
swap(x[0], x[1]);
swap(y[0], y[1]);
}
double det_y = y[1] - y[0], det_x = x[1] - x[0];
double k = det_y / det_x;
double b = 1. * y[0] - k * x[0];
line[++cnt] = make_pair(k, b);
update(1, UL, UR, x[0], x[1], cnt);
}
}
return 0;
}