Submission #1131421

#TimeUsernameProblemLanguageResultExecution timeMemory
1131421lanplotTeam Contest (JOI22_team)C++20
100 / 100
867 ms174792 KiB
#include <bits/stdc++.h> using namespace std; using ll = int; #define MAXN (1000005) struct node{ ll s,e,m; pair<ll,ll> v; node *l, *r; node(ll _s,ll _e){ s = _s; e = _e; m = (s + e) / 2; v = {-1e9,s}; if(s != e){ l = new node(s,m); r = new node(m + 1,e); } } void update(ll x,ll nval){ if(s == e){ v.first = max(v.first,nval); }else{ if(x > m) r -> update(x,nval); else l -> update(x,nval); v = max(l->v,r->v); } } pair<ll,ll> rmq(ll x,ll y){ if(s == x && e == y){ return v; }else{ if(x > m) return r->rmq(x,y); else if(y <= m) return l->rmq(x,y); else return max(l->rmq(x,m),r->rmq(m + 1,y)); } } } *rootBindtest, *rootCindtest, *rootBind, *rootCind; int main(){ ios_base::sync_with_stdio(false);cin.tie(0); ll N; cin>>N; rootBindtest = new node(0,3*N + 5); rootCindtest = new node(0,3*N + 5); rootBind = new node(0,3*N + 5); rootCind = new node(0,3*N + 5); pair<ll,pair<ll,ll> > arr[N]; //X, Y, Z vector<ll> d; for(ll i = 0;i < N;i++){ cin>>arr[i].first>>arr[i].second.first>>arr[i].second.second; d.push_back(arr[i].first); d.push_back(arr[i].second.first); d.push_back(arr[i].second.second); } sort(d.begin(),d.end()); d.resize(unique(d.begin(),d.end()) - d.begin()); for(ll i = 0;i < N;i++){ arr[i].first = lower_bound(d.begin(),d.end(),arr[i].first) - d.begin() + 1; arr[i].second.first = lower_bound(d.begin(),d.end(),arr[i].second.first) - d.begin() + 1; arr[i].second.second = lower_bound(d.begin(),d.end(),arr[i].second.second) - d.begin() + 1; } sort(arr,arr + N); deque<pair<ll,pair<ll,ll> > > waiting; ll ans = -1e9; for(ll i = 0;i < N;i++){ while(!waiting.empty() && waiting.front().first < arr[i].first){ ll bestC = -1e9; if(waiting.front().second.first > 0){ bestC = rootBindtest -> rmq(0,waiting.front().second.first - 1).first; } if(bestC != -1e9 && bestC > waiting.front().second.second){ rootBind -> update(waiting.front().second.first,waiting.front().second.first + bestC); } ll bestB = -1e9; if(waiting.front().second.second > 0){ bestB = rootCindtest -> rmq(0,waiting.front().second.second - 1).first; } if(bestB != -1e9 && bestB > waiting.front().second.first){ rootCind -> update(waiting.front().second.second,waiting.front().second.second + bestB); } rootBindtest -> update(waiting.front().second.first,waiting.front().second.second); rootCindtest -> update(waiting.front().second.second,waiting.front().second.first); waiting.pop_front(); } if(arr[i].second.first > 0){ pair<ll,ll> maxiBind = rootBind -> rmq(arr[i].second.first + 1,3*N + 5); if(maxiBind.first > 0){ ll B = maxiBind.second; ll C = maxiBind.first - maxiBind.second; if(C > arr[i].second.second){ ans = max(ans,d[arr[i].first - 1] + d[B - 1] + d[C - 1]); //need to minus 1 cos when I discretised, I made it 1-indexed to make it easier to implement } } } if(arr[i].second.second > 0){ pair<ll,ll> maxiCind = rootCind -> rmq(arr[i].second.second + 1,3*N + 5); if(maxiCind.first > 0){ ll C = maxiCind.second; ll B = maxiCind.first - maxiCind.second; if(B > arr[i].second.first){ ans = max(ans,d[arr[i].first - 1] + d[B - 1] + d[C - 1]); //need to minus 1 cos when I discretised, I made it 1-indexed to make it easier to implement } } } waiting.push_back(arr[i]); } if(ans == -1e9) cout<<-1<<'\n'; else cout<<ans<<'\n'; } /* Here is the Testcase Generator I used to debug in under 20 mins: #include <bits/stdc++.h> using namespace std; using ll = long long; #define MAXN (1000005) mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()); inline long long rand(long long x, long long y) { return rng() % (y+1-x) + x; } //inclusive pair<ll,pair<ll,ll> > arr[3]; //X, Y, Z ll N = 3; ll bruteforce(){ ll ans = -1e18; for(ll a = 0;a < N;a++){ for(ll b = 0;b < N;b++){ for(ll c = 0;c < N;c++){ if(a == b || a == c || b == c) continue; if(arr[a].first <= max(arr[b].first,arr[c].first)) continue; if(arr[b].second.first <= max(arr[a].second.first,arr[c].second.first)) continue; if(arr[c].second.second <= max(arr[a].second.second,arr[b].second.second)) continue; ans = max(ans,arr[a].first + arr[b].second.first + arr[c].second.second); } } } if(ans == -1e18) return -1; else return ans; } struct node{ ll s,e,m,lazy; pair<ll,ll> v; node *l = nullptr,*r = nullptr; //please remember to set to nullptr (if not it might RTE) node(ll _s,ll _e){ s = _s; e = _e; m = (s + e) / 2; v = {-1e18,s}; lazy = -1e18; } void create(){ if(l == nullptr && s != e){ l = new node(s,m); r = new node(m + 1,e); } } void propo(){ create(); if(lazy == -1e18) return; v.first = max(v.first,lazy); if(s != e){ l->lazy = max(l->lazy,lazy); r->lazy = max(r->lazy,lazy); } lazy = -1e18; } void update(ll x,ll nval){ if(s == e){ lazy = max(lazy,nval); }else{ create(); if(x > m) r -> update(x,nval); else l -> update(x,nval); l->propo(), r->propo(); v = max(l->v,r->v); } } pair<ll,ll> rmq(ll x,ll y){ create(); propo(); if(s == x && e == y){ return v; }else{ if(x > m) return r->rmq(x,y); else if(y <= m) return l->rmq(x,y); else return max(l->rmq(x,m),r->rmq(m + 1,y)); } } } *rootBindtest, *rootCindtest, *rootBind, *rootCind; ll mysol(){ rootBindtest = new node(0,1e8 + 5); rootCindtest = new node(0,1e8 + 5); rootBind = new node(0,1e8 + 5); rootCind = new node(0,1e8 + 5); sort(arr,arr + N); deque<pair<ll,pair<ll,ll> > > waiting; ll ans = -1e18; for(ll i = 0;i < N;i++){ while(!waiting.empty() && waiting.front().first < arr[i].first){ ll bestC = -1e18; if(waiting.front().second.first > 0){ bestC = rootBindtest -> rmq(0,waiting.front().second.first - 1).first; } if(bestC != -1e18){ rootBind -> update(waiting.front().second.first,waiting.front().second.first + bestC); } ll bestB = -1e18; if(waiting.front().second.second > 0){ bestB = rootCindtest -> rmq(0,waiting.front().second.second - 1).first; } if(bestB != -1e18){ rootCind -> update(waiting.front().second.second,waiting.front().second.second + bestB); } rootBindtest -> update(waiting.front().second.first,waiting.front().second.second); rootCindtest -> update(waiting.front().second.second,waiting.front().second.first); waiting.pop_front(); } if(arr[i].second.first > 0){ pair<ll,ll> maxiBind = rootBind -> rmq(arr[i].second.first + 1,1e8 + 5); if(maxiBind.first > 0){ ll C = maxiBind.first - maxiBind.second; if(C > arr[i].second.second){ ans = max(ans,arr[i].first + maxiBind.first); } } } if(arr[i].second.second > 0){ pair<ll,ll> maxiCind = rootCind -> rmq(arr[i].second.second + 1,1e8 + 5); if(maxiCind.first > 0){ ll B = maxiCind.first - maxiCind.second; if(B > arr[i].second.first){ ans = max(ans,arr[i].first + maxiCind.first); } } } waiting.push_back(arr[i]); } if(ans == -1e18) return -1; else return ans; } int main(){ ios_base::sync_with_stdio(false);cin.tie(0); ll t = 100; while(t--){ for(ll i = 0;i < N;i++){ arr[i].first = rand(1,5); arr[i].second.first = rand(1,5); arr[i].second.second = rand(1,5); } ll BRUTE = bruteforce(); ll MYSOL = mysol(); if(BRUTE != MYSOL){ cout<<"BRUTE: "<<BRUTE<<'\n'; cout<<"MYSOL: "<<MYSOL<<'\n'; for(ll i = 0;i < N;i++){ cout<<arr[i].first<<" "<<arr[i].second.first<<" "<<arr[i].second.second<<'\n'; } } } cout<<"THE END."<<'\n'; } Found the bug from running the t=100 Testcase Generator just once: BRUTE: -1 MYSOL: 14 1 3 5 2 5 5 4 1 1 BRUTE: -1 MYSOL: 13 3 5 2 4 5 3 5 2 1 BRUTE: -1 MYSOL: 10 1 3 3 1 5 5 2 3 1 BRUTE: -1 MYSOL: 12 3 3 1 3 3 5 4 1 1 BRUTE: -1 MYSOL: 12 2 2 4 2 4 5 4 1 1 THE END. */
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...