rt,思路是用平衡树维护接下来会跳到哪个点,关于线段的比较方式已经按照题解改过了,但还是又WA又TLE,求大佬捉虫。
#include<bits/stdc++.h>
#define y1 kylAKIOI
#define y2 IOIAKjk
#define N 100005
using namespace std;
struct fun
{
int l,r;
double k,b;
};
bool operator < (fun x,fun y)
{
if(x.r == y.r)return x.k*x.r+x.b > y.k*y.r+y.b;
else if(x.r < y.r)
{
double maxx = x.k*x.r+x.b;
double maxy = y.k*y.r+y.b;
double newk = (maxy-maxx)/(y.r-x.r);
return newk < y.k;
}
else return !(y<x);
}
const double eps = 1e-6;
bool operator == (fun x,fun y)
{
return x.l == y.l && x.r == y.r && abs(x.k-y.k)<eps && abs(x.b-y.b)<eps;
}
bool operator > (fun x,fun y)
{
return !(x<y || x==y);
}
fun get(int x1,int y1,int x2,int y2)
{
double k,b;
if(x1 == x2 && y1 == y2)
{
k = 0;
b = y1;
}
else
{
k = (y2-y1)*1.0/(x2-x1);
b = y1-k*x1;
}
fun ret;
ret.l = x1,ret.r = x2,ret.k = k,ret.b = b;
return ret;
}
int rt,tot;
struct node
{
int fa,son[2],cnt,sz;
fun v;
}t[N];
void clear(int u){t[u].fa = t[u].son[0] = t[u].son[1] = t[u].cnt = t[u].sz = t[u].v.k = t[u].v.b = t[u].v.l = t[u].v.r = 0;}
void upd(int u){t[u].sz = t[t[u].son[0]].sz + t[t[u].son[1]].sz + t[u].cnt;}
bool get(int u){return t[t[u].fa].son[1] == u;}
void rot(int u)
{
int k = get(u),v = t[u].fa,w = t[v].fa;
t[v].son[k] = t[u].son[k^1];
if(t[u].son[k^1])t[t[u].son[k^1]].fa = v;
t[u].son[k^1] = v;
t[v].fa = u,t[u].fa = w;
if(w)t[w].son[t[w].son[1] == v] = u;
upd(v),upd(u);
}
void splay(int u)
{
for(int v = t[u].fa;v = t[u].fa,v;rot(u))
if(t[v].fa)rot(get(u) == get(v)?v:u);
rt = u;
}
int build(fun x)
{
t[++tot].v = x;
t[tot].cnt = t[tot].sz = 1;
return tot;
}
void ins(int las,int u,fun x)
{
if(!u)
{
u = build(x);
// printf("OK!!\n");
// printf("OK!!we have inserted y=%lfx+%lf(%d<=x<%d)\n",x.k,x.b,x.l,x.r);
if(!rt)rt = u;
t[u].fa = las;
if(las)t[las].son[x > t[las].v] = u,upd(las);
splay(u);
return;
}
if(x == t[u].v)
{
t[u].cnt++;
upd(u);
splay(u);
return;
}
ins(u,t[u].son[x > t[u].v],x);
}
void fd(int u,fun x)
{
if(!u)return;
if(x < t[u].v)fd(t[u].son[0],x);
else if(x == t[u].v)
{
splay(u);
return;
}
else if(x > t[u].v)fd(t[u].son[1],x);
}
int pre()
{
int u = t[rt].son[0];
if(!u)return 0;
while(t[u].son[1])u = t[u].son[1];
splay(u);
return u;
}
int nxt()
{
int u = t[rt].son[1];
if(!u)return 0;
while(t[u].son[0])u = t[u].son[0];
splay(u);
return u;
}
void dfs(int u,int deep)
{
if(!u)return;
dfs(t[u].son[0],deep+1);
for(int i = 1;i <= deep;i++)printf(" ");
printf("y=%lfx+%lf (%d<=x<%d)",t[u].v.k,t[u].v.b,t[u].v.l,t[u].v.r);
printf(" <%d(%d)%d> (rt=%d)\n",t[u].son[0],u,t[u].son[1],rt);
dfs(t[u].son[1],deep+1);
}
void del(fun x)
{
fd(rt,x);
int u = rt;
if(t[u].cnt > 1)
{
t[u].cnt--;
upd(u);
return;
}
if(!t[u].son[0] && !t[u].son[1])
{
rt = 0;
clear(u);
return;
}
if(t[u].son[0] && !t[u].son[1])
{
rt = t[u].son[0];
t[rt].fa = 0;
clear(u);
return;
}
if(!t[u].son[0] && t[u].son[1])
{
rt = t[u].son[1];
t[rt].fa = 0;
clear(u);
return;
}
rt = pre();
t[rt].son[1] = t[u].son[1];
t[t[u].son[1]].fa = rt;
upd(rt);
clear(u);
}
int n,ans;
fun a[N];
bool cmp(fun x,fun y)
{
return x.l < y.l;
}
priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > > q;
int main()
{
scanf("%d",&n);
for(int i = 1;i <= n;i++)
{
int x1,y1,x2,y2;
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
a[i] = get(x1,y1,x2,y2);
}
sort(a+2,a+1+n,cmp);
ans = 1;
int nowx = a[1].r,nowy = a[1].k*a[1].r+a[1].b;
int it = 2;
while(1)
{
while(!q.empty() && q.top().first <= nowx)
{
del(a[q.top().second]);
q.pop();
}
while(nowx >= a[it].l && it <= n)
{
ins(0,rt,a[it]);
q.push(make_pair(a[it].r,it));
it++;
}
ins(0,rt,get(nowx,nowy,nowx,nowy));
int u = nxt();
if(!u)break;
del(get(nowx,nowy,nowx,nowy));
nowx = t[u].v.r;
nowy = t[u].v.k * t[u].v.r + t[u].v.b;
ans++;
}
return printf("%d\n",ans),0x0;
}