QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#737014 | #9569. Subway | billf | WA | 3ms | 33796kb | C++14 | 4.0kb | 2024-11-12 14:15:12 | 2024-11-12 14:15:16 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<LL, int> PLI;
typedef pair<int, int> PII;
#define fr first
#define sc second
const int N = 2e5 + 10, M = 4e5 + 10;
const double eps = 1e-9, INF = 1e18;
int n, m, a[N], b[N];
int ln[N], num;
PII o[M];
vector<int> sub[N];
int tot, ver[N], nxt[N], fst[M], wei[N];
LL dis[M], ans[N];
void add(int ui, int vi, int wi)
{
ver[++tot] = vi, wei[tot] = wi, nxt[tot] = fst[ui];
fst[ui] = tot;
}
priority_queue<PLI, vector<PLI>, greater<PLI>> hp;
// vector<PII> prc[N];
set<PII> prc[N];
struct line
{
LL k, b;
double p;
};
vector<line> h[N];
double cal(line x, line y)
{
if (x.k == y.k)
return INF;
return (x.b - y.b) * 1.0 / (y.k - x.k);
}
int main()
{
cin >> n >> m;
for (int i = 1; i <= m; i++)
scanf("%d", a + i);
for (int i = 1; i <= m; i++)
scanf("%d", b + i);
memset(dis, 0x3f, sizeof dis);
for (int i = 1; i <= m; i++)
{
scanf("%d", ln + i);
sub[i].resize(ln[i]);
for (int j = 0; j < ln[i]; j++)
{
int poi, cst;
scanf("%d", &poi);
o[++num] = make_pair(poi, i);
sub[i][j] = num;
if (poi == 1)
dis[num] = 0, hp.push({0, num}); //, cout << num << ' ' << o[num].fr << " " << o[num].sc << endl;
else
prc[poi].insert({a[i], num});
if (j + 1 < ln[i])
{
scanf("%d", &cst);
add(num, num + 1, cst);
}
}
}
// for (auto it : prc[3])
// cout << it.sc << ' ';
// cout << endl;
while (!hp.empty())
{
auto now = hp.top();
hp.pop();
int u = now.sc, v, w, id = o[u].fr, sy = o[u].sc;
if (now.fr != dis[u])
continue;
line st, up;
st.k = b[sy];
st.b = dis[u];
st.p = 0;
if (h[id].empty())
h[id].push_back(st);
else if (!prc[id].empty())
{
up = *(--h[id].end());
for (int ll = h[id].size(); ll && cal(h[id][ll - 1], st) - h[id][ll - 1].p > -eps;
ll--, up = h[id][ll], h[id].pop_back())
;
// cout << st.k << " " << up.k << " " << st.b << " " << up.b << endl;
if (up.k != st.k)
up.p = cal(up, st);
else
up.p = 0;
// printf("%lld %lld %.3lf\n", up.b - st.b, st.k - up.k, up.p);
h[id].push_back(up);
h[id].push_back(st);
// cerr << u << " - " << id << " " << st.p << endl;
}
if (prc[id].find({a[sy], u}) != prc[id].end())
prc[id].erase(prc[id].find({a[sy], u})); //, cerr << u << " " << id << '\n';
// else
// cerr << u << endl;
if (!prc[id].empty())
{
int l = 0, r = h[id].size() - 1, mid;
int pos = (*prc[id].begin()).sc, nn = a[o[pos].sc];
while (l < r)
{
mid = l + r >> 1;
if (nn < h[id][mid].p)
l = mid + 1;
else
r = mid;
}
st = h[id][l];
if (dis[pos] > st.b + st.k * nn)
{
dis[pos] = st.b + st.k * nn;
hp.push({dis[pos], pos});
}
// cerr << u << " " << pos << " " << dis[u] << " " << dis[pos] << endl;
}
for (int i = fst[u]; i; i = nxt[i])
{
v = ver[i], w = wei[i];
if (dis[v] > dis[u] + w)
{
dis[v] = dis[u] + w;
hp.push({dis[v], v});
}
}
}
memset(ans, 0x3f, sizeof ans);
for (int i = 1; i <= num; i++)
ans[o[i].fr] = min(ans[o[i].fr], dis[i]);
for (int i = 2; i <= n; i++)
printf("%lld ", ans[i]);
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 0ms
memory: 32892kb
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: 0ms
memory: 33796kb
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
Wrong Answer
time: 3ms
memory: 31568kb
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
output:
817370554 15849621 162075978395 701911826
result:
wrong answer 3rd numbers differ - expected: '80811085745', found: '162075978395'