QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#737014#9569. SubwaybillfWA 3ms33796kbC++144.0kb2024-11-12 14:15:122024-11-12 14:15:16

Judging History

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

  • [2024-11-12 14:15:16]
  • 评测
  • 测评结果:WA
  • 用时:3ms
  • 内存:33796kb
  • [2024-11-12 14:15:12]
  • 提交

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'