QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#121883#5458. Shortest Path Query6arenTL 0ms3580kbC++173.0kb2023-07-08 23:21:422024-06-21 12:38:03

Judging History

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

  • [2024-06-21 12:38:03]
  • 管理员手动重测本题所有提交记录
  • 测评结果:TL
  • 用时:0ms
  • 内存:3580kb
  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2023-07-08 23:21:45]
  • 评测
  • 测评结果:0
  • 用时:0ms
  • 内存:3456kb
  • [2023-07-08 23:21:42]
  • 提交

answer

#include <bits/stdc++.h>

using namespace std;

#ifdef LOCAL
#include <cp/debugger.hpp>
#else
#define debug(...) 42
#endif

#define sz(v) ((int)(v).size())
#define all(v) (v).begin(), (v).end()

typedef int64_t int64;
typedef pair<int, int> ii;

using T = int64;
struct Point {
  T x;
  T y;

  Point(T x, T y) : x(x), y(y) {}

  Point &operator+=(const Point &p) {
    x += p.x, y += p.y;
    return *this;
  }

  Point &operator-=(const Point &p) {
    x -= p.x, y -= p.y;
    return *this;
  }

  Point &operator*=(const T &v) {
    x *= v, y *= v;
    return *this;
  }

  friend Point operator-(const Point &p) { return Point(-p.x, -p.y); }
  friend Point operator+(Point lhs, const Point &rhs) { return lhs += rhs; }
  friend Point operator-(Point lhs, const Point &rhs) { return lhs -= rhs; }
  friend Point operator*(Point lhs, const T &rhs) { return lhs *= rhs; }
};

T dot(const Point &a, const Point &b) { return a.x * b.x + a.y * b.y; }

T cross(const Point &a, const Point &b) { return a.x * b.y - a.y * b.x; }

string to_string(Point p) { return "(" + to_string(p.x) + ", " + to_string(p.y) + ")"; }

void add(vector<Point> &hull, Point p) {
  while (hull.size() >= 2 && cross(hull.end()[-1] - hull.end()[-2], p - hull.end()[-1]) < 0) hull.pop_back();
  hull.push_back(p);
}

vector<Point> merge(const vector<Point> &a, const vector<Point> &b) {
  vector<Point> res;
  int l1 = 0, l2 = 0;
  while (l1 < a.size() || l2 < b.size()) {
    if (l1 < a.size() && l2 < b.size()) {
      if (a[l1].x < b[l2].x)
        add(res, a[l1]), l1++;
      else
        add(res, b[l2]), l2++;
    } else if (l1 < a.size()) {
      add(res, a[l1]), l1++;
    } else {
      add(res, b[l2]), l2++;
    }
  }

  return res;
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  int n, m;
  cin >> n >> m;
  vector<vector<array<int, 2>>> g(n);
  for (int i = 0; i < m; i++) {
    int u, v, c;
    cin >> u >> v >> c;
    u--, v--;
    g[v].push_back({u, c});
  }

  vector<vector<array<int, 3>>> queries(n);
  int q;
  cin >> q;
  for (int i = 0; i < q; i++) {
    int a, b, x;
    cin >> a >> b >> x;
    x--;
    queries[x].push_back({a, b, i});
  }

  const int D = 1024;
  vector<vector<Point>> hull(D);
  hull[0].push_back(Point(0, 0));

  vector<int64> res(q);

  for (int i = 1; i < n; i++) {
    for (auto [v, c] : g[i]) {
      for (auto &p : hull[v % D]) {
        if (c == 0)
          p.x++;
        else
          p.y++;
      }
      hull[i % D] = merge(hull[i % D], hull[v % D]);
      for (auto &p : hull[v % D]) {
        if (c == 0)
          p.x--;
        else
          p.y--;
      }
    }
    for (auto [a, b, id] : queries[i]) {
      int64 ans = 1e18;
      Point q(a, b);
      for (auto p : hull[i % D]) {
        ans = min(ans, dot(p, q));
      }
      res[id] = ans;
    }
  }

  for (int i = 0; i < q; i++) {
    cout << res[i] << '\n';
  }

  return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 0ms
memory: 3580kb

input:

4 4
1 2 0
1 3 1
2 4 0
3 4 1
3
3 5 2
3 2 4
2 3 4

output:

3
4
4

result:

ok 3 number(s): "3 4 4"

Test #2:

score: -100
Time Limit Exceeded

input:

50000 100000
1 2 1
2 3 0
3 4 1
4 5 0
5 6 1
6 7 0
7 8 1
8 9 1
9 10 0
10 11 1
11 12 1
12 13 1
13 14 0
14 15 0
15 16 0
16 17 0
17 18 1
18 19 1
19 20 0
20 21 1
21 22 0
22 23 0
23 24 1
24 25 1
25 26 0
26 27 1
27 28 0
28 29 0
29 30 0
30 31 0
31 32 1
32 33 0
33 34 1
34 35 1
35 36 1
36 37 1
37 38 0
38 39 0
...

output:


result: