Submission #47179

#TimeUsernameProblemLanguageResultExecution timeMemory
47179platypusJakarta Skyscrapers (APIO15_skyscraper)C++17
36 / 100
1092 ms127564 KiB
#include <cstdio> #include <cstdlib> #include <cmath> #include <climits> #include <cfloat> #include <cstring> #include <map> #include <utility> #include <set> #include <iostream> #include <memory> #include <string> #include <vector> #include <list> #include <algorithm> #include <functional> #include <sstream> #include <complex> #include <stack> #include <queue> #include <unordered_set> #include <unordered_map> #include <array> #include <cassert> #include <bitset> using namespace std; using LL = long long; namespace std { template <> class hash<std::pair<int, int>> { public: size_t operator()(const std::pair<int, int>& x) const { //return hash<int>()(x.first) ^ hash<int>()(x.second); return (size_t)(x.second ^ x.first + 0x9e3779b9 + (x.second << 6) + (x.second >> 2)); } }; } //Vは比較可能な値にする template <typename V> class Graph { private: //unordered_map<V, vector<pair<V, LL>>>edge; vector<pair<pair<V, V>, LL>>raw; vector<V>vset; public: //from->toへcostの辺を張る void addEdge(V from, V to, LL cost) { //edge[from].push_back(make_pair(to, cost)); raw.push_back(make_pair(make_pair(from, to), cost)); vset.push_back(from); vset.push_back(to); } //v1とv2間にcostの辺を張る void addUndirectedEdge(V v1, V v2, LL cost) { //edge[v1].push_back(make_pair(v2, cost)); //edge[v2].push_back(make_pair(v1, cost)); raw.push_back(make_pair(make_pair(v1, v2), cost)); raw.push_back(make_pair(make_pair(v2, v1), cost)); vset.push_back(v1); vset.push_back(v2); } //最短を求める LL dijkstra(V start, V finish) { sort(vset.begin(), vset.end()); vset.erase(unique(vset.begin(), vset.end()), vset.end()); int vnum = vset.size(); vector<LL>disti(vnum, LLONG_MAX / 9); map<V, int>inv; for (int i = 0; i < vnum; ++i) { inv[vset[i]] = i; } vector<vector<pair<int, LL>>>edgei(vnum); for (auto& e : raw) { edgei[inv[e.first.first]].push_back(make_pair(inv[e.first.second], e.second)); } //dist[start] = 0; //priority_queue<pair<LL, V>, vector<pair<LL, V>>, greater<pair<LL, V>>>que; disti[inv[start]] = 0; priority_queue<pair<LL, int>, vector<pair<LL, int>>, greater<pair<LL, int>>>que; que.push(make_pair(0LL, inv[start])); while (!que.empty()) { auto q = que.top(); que.pop(); int now = q.second; LL dis = q.first; if (disti[now] < dis) continue; for (auto e : edgei[now]) { int nxt = e.first; LL cost = e.second; if (/*!disti.count(nxt) ||*/ disti[nxt] > disti[now] + cost) { disti[nxt] = disti[now] + cost; que.push(make_pair(disti[nxt], nxt)); } } } for (int i = 0; i < vnum; ++i) { //dist[vset[i]] = disti[i]; if (vset[i] == finish) { return disti[i]; } } abort(); } }; int N, M; int mceil(int a, int b) { if (a == 0)return 0; return (a - 1) / b + 1; } int main(void) { //cin >> N >> M; scanf("%d %d", &N, &M); using P = pair<int, int>; map<P, vector<int>>mp; int st = -1; int enb = -1, enp = -1, enr = -1; for (int i = 0; i < M; ++i) { int b, p; //cin >> b >> p; scanf("%d %d", &b, &p); if (i == 0)st = b; if (i == 1) { enb = b; enp = p; enr = b % p; } int rem = b % p; mp[make_pair(p, rem)].push_back(b); } Graph<P>G; for (auto elm : mp) { int p = elm.first.first; int rem = elm.first.second; auto& v = elm.second; int len = mceil(N - rem, p); vector<LL>dist(len, INT_MAX); for (int x : v)dist[x / p] = 0; /*for (int i = 1; i < len; ++i) { dist[i] = min(dist[i - 1] + 1, dist[i]); } for (int i = len - 1; i > 0; --i) { dist[i - 1] = min(dist[i] + 1, dist[i - 1]); }*/ for (int i = 0; i < len; ++i) { if (dist[i] < INT_MAX)G.addEdge(P(0, i * p + rem), P(p, i * p + rem), dist[i]); G.addEdge(P(p, i * p + rem), P(0, i * p + rem), 0LL); } for (int i = 1; i < len; ++i) { G.addUndirectedEdge(P(p, (i - 1)*p + rem), P(p, i*p + rem), 1LL); } } int len = mceil(N - enr, enp); for (int i = 0; i < len; ++i) { if (abs(i - (enb / enp)) == 0) G.addEdge(P(0, i * enp + enr), P(N, i * enp + enr), abs(i - (enb / enp))); } P endv{}; for (int i = 0; i < len; ++i) { if (abs(i - (enb / enp)) == 0) endv = P(N, i * enp + enr); } LL ans = G.dijkstra(P(0, st), endv); if (ans >= LLONG_MAX / 9) { //cout << -1 << endl; printf("-1\n"); } else { //cout << ans << endl; printf("%lld\n", ans); } return 0; }

Compilation message (stderr)

skyscraper.cpp: In member function 'std::size_t std::hash<std::pair<int, int> >::operator()(const std::pair<int, int>&) const':
skyscraper.cpp:36:70: warning: suggest parentheses around arithmetic in operand of '^' [-Wparentheses]
    return (size_t)(x.second ^ x.first + 0x9e3779b9 + (x.second << 6) + (x.second >> 2));
                               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~
skyscraper.cpp: In function 'int main()':
skyscraper.cpp:119:7: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  scanf("%d %d", &N, &M);
  ~~~~~^~~~~~~~~~~~~~~~~
skyscraper.cpp:127:8: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
   scanf("%d %d", &b, &p);
   ~~~~~^~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...