QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#733135#5540. City HallSuhyRE 0ms0kbC++144.8kb2024-11-10 17:23:242024-11-10 17:23:25

Judging History

你现在查看的是最新测评结果

  • [2024-11-10 17:23:25]
  • 评测
  • 测评结果:RE
  • 用时:0ms
  • 内存:0kb
  • [2024-11-10 17:23:24]
  • 提交

answer

#include <bits/stdc++.h>
#define ll long long
#define ld long double

using namespace std;

const int maxn = 100005;

class Line 
{
    public:
    static ll L, R;
    #define int ld
    int ax, ay, bx, by;
    ld eps = 1e-9;
    Line (int Ax, int Ay, int Bx, int By)
    {
        if(Ax > Bx)
        {
            swap(Ax, Bx);
            swap(Ay, By);
        }
        ax = Ax; ay = Ay; bx = Bx; by = By ;
    }
    Line (int k, int b)
        {ax = L; bx = R; ay = k * L + b; by = k * R + b;}

    bool chk(int l, int r)
        {return ax <= l && r <= bx;}
    ld getval(int x)
    {
        if(ax == bx) return max(ay, by);
        return (ld) ay + (ld) (x - ax) / (bx - ax) * (by - ay);
    }

    // a.comp(b, x) => a(x) > b(x), a 被优先选中

    bool comp(Line b, int x)
        {return (getval(x) - b.getval(x) < -eps);}
    
    #undef int
};

#define int long long

class LiCT
{
    public:
    static int L, R;
    vector <Line> lin;
    vector <int> lzt, lson, rson;
    int cnt = -1;
    int CrtP()
    {
        lzt.push_back(-1);
        lson.push_back(0);
        rson.push_back(0);
        return ++ cnt;
    }
    LiCT()
        {CrtP();}
    int Gson(vector <int> &vec, int in)
    {
        if(vec[in] == 0)
            vec[in] = CrtP();
        return vec[in];
    }
    void inst(int in, int l, int r, int x)
    {
        int mid = (l + r) >> 1;
        if(!lin[x].chk(l, r))
        {
            if(lin[x].ax <= mid)
                inst(Gson(lson, in), l, mid, x);
            if(lin[x].bx > mid)
                inst(Gson(rson, in), mid + 1, r, x);
            return;
        }
        if(lzt[in] == -1)
        {
            lzt[in] = x;
            return;
        }
        if(lin[x].comp(lin[lzt[in]], mid))
            swap(lzt[in], x);
        if(l == r) return;
        if(lin[x].comp(lin[lzt[in]], l))
            inst(Gson(lson, in), l, mid, x);
        if(lin[x].comp(lin[lzt[in]], r))
            inst(Gson(rson, in), mid + 1, r, x);
    }
    int ask(int in, int l, int r, int x)
    {
        if(l == r) return lzt[in];
        int mid = (l + r) >> 1;
        int ans = -1;
        if(x <= mid && lson[in])
            ans = ask(lson[in], l, mid, x);
        else if(x > mid && rson[in])
            ans = ask(rson[in], mid + 1, r, x);
        if(lzt[in] != -1 && (ans == -1 || lin[lzt[in]].comp(lin[ans], x)))
            ans = lzt[in];
        return ans;
    }
    void ins(Line &a)
    {
        lin.push_back(a);
        inst(0, L, R, lin.size() - 1);
    }

    //ask 返回 vector lin 中答案的编号
    //使用 ins() 进行插入
    //根为 0 号节点
};

int read()
{
   int x = 0, fl = 0;
   char c = 0;
   while(c < '0' || '9' < c)
      c = getchar(), fl |= (c == '-');
   while('0' <= c && c <= '9')
      x = x * 10 + c - '0', c = getchar();
   return (fl ? -x : x);
}

void dij(vector <pair <int, int>> pic[], int sp[], int n, int s, int inf)
{
    #define st first 
    #define nd second
    #define pii pair <int, int>
    int vis[n + 3] = {0};
    priority_queue <pii, vector <pii>, greater <pii> > que;
    for(int i = 1; i <= n; i ++)
        sp[i] = inf;
    sp[s] = 0;
    que.push({0, s});
    while(que.size())
    {
        int in = que.top().nd;
        que.pop();
        if(vis[in]) continue;
        vis[in] = 1;
        for(auto i : pic[in])
            if(sp[i.st] > sp[in] + i.nd)
                que.push({sp[i.st] = sp[in] + i.nd, i.st});
    }
}

int inf = 100000000000000000LL;
int n, m, s, t;
int sps[maxn], spt[maxn];
int h[maxn];
vector <pii> pic[maxn];
int LiCT::L = 0;
int Line::L = 0;
int LiCT::R = 100000;
int Line::R = 100000;

int calc(int x, int y)
{
    return (h[x] - h[y]) * (h[x] - h[y]);
}

signed main()
{
    cin>>n>>m>>s>>t;
    for(int i = 1; i <= n; i ++)
        h[i] = read();
    for(int i = 1; i <= m; i ++)
    {
        int u = read(), v = read();
        pic[u].push_back({v, calc(u, v)});
        pic[v].push_back({u, calc(u, v)});
    }
    dij(pic, sps, n, s, inf);
    dij(pic, spt, n, t, inf);
    ld ans = inf;
    for(auto i : pic[s]) ans = min(ans, (ld) spt[i.st]);
    for(auto i : pic[t]) ans = min(ans, (ld) sps[i.st]);
    //cout<<ans<<endl;
    for(int i = 1; i <= n; i ++)
    {
        if(i == s || i == t) continue;
        LiCT lct;
        for(auto j : pic[i])
        {
            Line lin(-h[j.st], (ld) spt[j.st] + (ld) 0.5 * h[j.st] * h[j.st]);
            lct.ins(lin);
        }
        for(auto j : pic[i])
        {
            int li = lct.ask(0, 0, 100000, h[j.st]);
            //cout<<li<<endl;
            li = lct.lin[li].getval(h[j.st]);
            ans = min(ans, (ld)sps[j.st] + (ld) 0.5 * h[j.st] * h[j.st] + li);
        }
    }
    cout<<fixed<<setprecision(10)<<ans<<endl;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 0
Runtime Error

input:

5 6 1 3
5 100 8 2 10
1 2
2 3
2 5
1 4
4 5
3 5

output:


result: