QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#735734 | #9569. Subway | propane | RE | 48ms | 152136kb | C++20 | 5.5kb | 2024-11-11 21:29:30 | 2024-11-11 21:29:31 |
Judging History
answer
#include<iostream>
#include<cstring>
#include<deque>
#include<vector>
#include<cassert>
#include<queue>
#include<algorithm>
using namespace std;
using LL = long long;
template <typename T, bool isMin>
struct ConvexHullTrickAddMonotone{
#define F first
#define S second
using P = pair<T, T>;
deque<P> H;
ConvexHullTrickAddMonotone() = default;
bool empty() const { return H.empty(); }
void clear() { H.clear(); }
inline int sgn(T x) { return x == 0 ? 0 : (x < 0 ? -1 : 1); }
inline bool check(const P &a, const P &b, const P &c){
if (b.S == a.S || c.S == b.S)
return sgn(b.F - a.F) * sgn(c.S - b.S) >= sgn(c.F - b.F) * sgn(b.S - a.S);
// return (b.F-a.F)*(c.S-b.S) >= (b.S-a.S)*(c.F-b.F);
if (is_integral<T>::value){
return __int128_t(c.S - b.S) * sgn(c.F - b.F) * abs(b.F - a.F) >=
__int128_t(b.S - a.S) * sgn(b.F - a.F) * abs(c.F - b.F);
// return (b.S - a.S) / (a.F - b.F) >= (c.S - b.S) / (b.F - c.F);
}
else{
return (b.F - a.F) * sgn(c.S - b.S) / abs(b.S - a.S) >=
(c.F - b.F) * sgn(b.S - a.S) / abs(c.S - b.S);
}
}
void add(T a, T b){
if (!isMin)
a *= -1, b *= -1;
P line(a, b);
if (empty()){
H.emplace_front(line);
return;
}
if (H.front().F <= a){
if (H.front().F == a){
if (H.front().S <= b)
return;
H.pop_front();
}
while (H.size() >= 2 && check(line, H.front(), H[1]))
H.pop_front();
H.emplace_front(line);
}
else{
assert(a <= H.back().F);
if (H.back().F == a){
if (H.back().S <= b)
return;
H.pop_back();
}
while (H.size() >= 2 && check(H[H.size() - 2], H.back(), line))
H.pop_back();
H.emplace_back(line);
}
}
inline T get_y(const P &a, const T &x){
return a.F * x + a.S;
}
T query(T x){
assert(!empty());
int l = -1, r = H.size() - 1;
while (l + 1 < r){
int m = (l + r) >> 1;
if (get_y(H[m], x) >= get_y(H[m + 1], x))
l = m;
else
r = m;
}
if (isMin)
return get_y(H[r], x);
return -get_y(H[r], x);
}
T query_monotone_inc(T x){
assert(!empty());
while (H.size() >= 2 && get_y(H.front(), x) >= get_y(H[1], x))
H.pop_front();
if (isMin)
return get_y(H.front(), x);
return -get_y(H.front(), x);
}
T query_monotone_dec(T x){
assert(!empty());
while (H.size() >= 2 && get_y(H.back(), x) >= get_y(H[H.size() - 2], x))
H.pop_back();
if (isMin)
return get_y(H.back(), x);
return -get_y(H.back(), x);
}
#undef F
#undef S
};
const int maxn = 2e5 + 5;
ConvexHullTrickAddMonotone<LL, true> CHT[maxn];
vector<pair<int, int> > vs[maxn];
pair<int, int> nxt[maxn];
vector<int> lines[maxn * 3];
int pos[maxn * 3], bel[maxn * 3], pt[maxn];
LL d[maxn * 3], ans[maxn];
bool v[maxn * 3];
int main(){
#ifdef LOCAL
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
#endif
cin.tie(0);
cout.tie(0);
ios::sync_with_stdio(0);
int n, k;
cin >> n >> k;
vector<int> a(k + 1), b(k + 1);
for(int i = 1; i <= k; i++) cin >> a[i];
for(int i = 1; i <= k; i++) cin >> b[i];
int idx = 0;
for(int i = 1; i <= k; i++){
int c;
cin >> c;
vector<int> v(c), e(c - 1);
for(int j = 0; j < 2 * c - 1; j++){
int x;
cin >> x;
if (j % 2 == 0) v[j / 2] = x;
else e[j / 2] = x;
}
vector<int> id(c);
for(int j = 0; j < c; j++){
id[j] = ++idx;
pos[idx] = v[j];
bel[idx] = i;
vs[v[j]].push_back({idx, i});
}
for(int j = 0; j + 1 < c; j++){
nxt[id[j]] = {id[j + 1], e[j]};
}
}
for(int i = 1; i <= n; i++){
sort(vs[i].begin(), vs[i].end(), [&](pair<int, int> x, pair<int, int> y){
return b[x.second] < b[y.second];
});
}
using P = pair<LL, int>;
priority_queue<P, vector<P>, greater<P> > q;
memset(d, 0x3f, sizeof d);
memset(ans, 0x3f, sizeof ans);
for(auto [v_id, line_id] : vs[1]){
d[v_id] = 0;
q.push({d[v_id], v_id});
}
while(!q.empty()){
auto [_, x] = q.top();
q.pop();
if (v[x]) continue;
v[x] = true;
int y = pos[x];
ans[y] = min(ans[y], d[x]);
CHT[y].add(b[bel[x]], d[x]);
while(pt[y] < vs[y].size() and v[vs[y][pt[y]].first]){
pt[y]++;
}
if (pt[y] < vs[y].size()){
auto [v_id, line_id] = vs[y][pt[y]];
LL val = CHT[y].query(a[line_id]);
if (val < d[v_id]){
d[v_id] = val;
q.push({d[v_id], v_id});
}
}
if (nxt[x].first and d[nxt[x].first] > d[x] + nxt[x].second){
d[nxt[x].first] = d[x] + nxt[x].second;
q.push({d[nxt[x].first], nxt[x].first});
}
}
for(int i = 2; i <= n; i++){
cout << ans[i] << " \n"[i == n];
}
}
詳細信息
Test #1:
score: 100
Accepted
time: 48ms
memory: 151504kb
input:
6 3 1 5 1 5 5 1 3 1 2 2 3 3 3 5 1 2 1 4 3 3 4 5 4 6
output:
2 5 21 14 18
result:
ok 5 number(s): "2 5 21 14 18"
Test #2:
score: 0
Accepted
time: 39ms
memory: 152136kb
input:
6 3 1 5 1 5 5 1 5 1 2 2 100 3 100 6 1 4 5 1 100 2 4 3 100 5 1 4 2 3 1 5
output:
2 31 43 37 136
result:
ok 5 number(s): "2 31 43 37 136"
Test #3:
score: -100
Runtime Error
input:
5 9 278281 70119 511791 834898 25300 63487 609134 236836 394497 835557 287345 579404 879128 636344 306393 569430 152565 47119 2 3 823004250 4 2 1 25427550 3 2 1 15849621 3 2 1 701911826 5 3 5 679672631 3 907176714 2 2 1 817370554 2 2 3 697987914 2 2 4 873900795 2 2 1 814305954 5