Submission #697055

#TimeUsernameProblemLanguageResultExecution timeMemory
697055Cross_RatioTreatment Project (JOI20_treatment)C++14
39 / 100
3043 ms316168 KiB
#include <bits/stdc++.h> #define int long long using namespace std; typedef long long ll; const ll INF = 1e18; int T[100005]; int L[100005]; int R[100005]; ll C[100005]; vector<array<ll, 2>> adj[800005]; ll dis[200005]; bool vis[200005]; typedef pair<int, int> P; struct SegTree { struct Node { set<array<int, 2>> S1, S2; }; vector<Node> seg; int MAX; SegTree(int N) { int i; for(i=1;i<2*N;i*=2) {} seg.resize(i); MAX = i; } void Edit(int n, int a) { n += MAX/2; seg[n].S1.insert({L[a] + T[a], 2*a}); seg[n].S2.insert({L[a] - T[a], 2*a}); n /= 2; while(n) { seg[n].S1.insert({L[a] + T[a], 2*a}); seg[n].S2.insert({L[a] - T[a], 2*a}); n /= 2; } } void make_edge(int s, int e, int k, int n, int ns, int ne, bool type) { if(e<=ns||ne<=s) return; if(s<=ns&&ne<=e) { if(type) { while(!seg[n].S2.empty()) { auto m = *seg[n].S2.begin(); if(m[0] > R[k] - T[k] + 1) break; adj[2*k+1].push_back({m[1], 0}); seg[n].S2.erase(m); } } else { while(!seg[n].S1.empty()) { auto m = *seg[n].S1.begin(); if(m[0] > R[k] + T[k] + 1) break; adj[2*k+1].push_back({m[1], 0}); seg[n].S1.erase(m); } } return; } int mid = ns + ne >> 1; make_edge(s, e, k, 2*n, ns, mid, type); make_edge(s, e, k, 2*n+1, mid, ne, type); } }; vector<int> idt; int it(int n) { return lower_bound(idt.begin(),idt.end(),n) - idt.begin(); } signed main() { cin.sync_with_stdio(false); cin.tie(0); cout.tie(0); int N, M; cin >> N >> M; int i, j; for(i=1;i<=M;i++) { cin >> T[i] >> L[i] >> R[i] >> C[i]; idt.push_back(T[i]); } sort(idt.begin(),idt.end()); idt.erase(unique(idt.begin(),idt.end()),idt.end()); //0 is left, 1 is right //2i is input, 2i+1 is output for(i=1;i<=M;i++) { adj[2*i].push_back({2*i+1, C[i]}); if(L[i]==1) adj[0].push_back({2*i, 0}); if(R[i]==N) adj[2*i+1].push_back({1, 0}); } /*for(i=1;i<=M;i++) { for(j=1;j<=M;j++) { if(i==j) continue; if(T[i] >= T[j]) { int t = T[i] - T[j]; if(R[j] == N || L[i] <= R[j] - t + 1) { adj[2*j+1].push_back({2*i, 0}); } } if(T[i] <= T[j]) { int t = T[j] - T[i]; if(L[i] == 1 || L[i] - 1 + t <= R[j]) { adj[2*j+1].push_back({2*i, 0}); } } } }*/ /*for(i=0;i<=2*M+1;i++) { cout << i << " : "; for(auto n2 : adj[i]) { cout << "(" << n2[0] << ", " << n2[1] << ") "; } cout << '\n'; }*/ SegTree tree(idt.size() + 3); int MAX = tree.MAX; for(i=1;i<=M;i++) { tree.Edit(it(T[i]), i); } for(i=0;i<=2*M+1;i++) dis[i] = INF; dis[0] = 0; priority_queue<P, vector<P>, greater<P>> PQ; PQ.push(P(0, 0)); while(!PQ.empty()) { auto k = PQ.top(); PQ.pop(); int id = k.second; if(vis[id]) continue; vis[id] = true; if(id != 0 && id != 1 && id % 2 == 1) { int x = id / 2; tree.make_edge(0, it(T[x])+1, x, 1, 0, MAX/2, true); tree.make_edge(it(T[x]), idt.size(), x, 1, 0, MAX/2, false); } for(auto n : adj[id]) { if(dis[n[0]] > dis[id] + n[1]) { dis[n[0]] = dis[id] + n[1]; PQ.push(P(dis[n[0]], n[0])); } } } cout << (dis[1]==INF?-1:dis[1]); }

Compilation message (stderr)

treatment.cpp: In member function 'void SegTree::make_edge(long long int, long long int, long long int, long long int, long long int, long long int, bool)':
treatment.cpp:58:22: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   58 |         int mid = ns + ne >> 1;
      |                   ~~~^~~~
treatment.cpp: In function 'int main()':
treatment.cpp:73:12: warning: unused variable 'j' [-Wunused-variable]
   73 |     int i, j;
      |            ^
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...