QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#733135 | #5540. City Hall | Suhy | RE | 0ms | 0kb | C++14 | 4.8kb | 2024-11-10 17:23:24 | 2024-11-10 17:23:25 |
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;
}
详细
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