求调玄关,蒟蒻已经调傻了

P3081 [USACO13MAR] Hill Walk G

luxiaomao @ 2024-11-20 21:52:50

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

by Lele_Programmer @ 2024-11-20 22:12:17

@luxiaomao %%%


|