제출 #1171292

#제출 시각아이디문제언어결과실행 시간메모리
1171292Zbyszek99Two Dishes (JOI19_dishes)C++20
82 / 100
874 ms229660 KiB
#include <bits/stdc++.h> #include <ext/pb_ds/assoc_container.hpp> #include <ext/pb_ds/tree_policy.hpp> #define ll long long #define ld long double #define ull unsigned long long #define ff first #define ss second #define pii pair<int,int> #define pll pair<long long, long long> #define vi vector<int> #define vl vector<long long> #define pb push_back #define rep(i, b) for(int i = 0; i < (b); ++i) #define rep2(i,a,b) for(int i = a; i <= (b); ++i) #define rep3(i,a,b,c) for(int i = a; i <= (b); i+=c) #define count_bits(x) __builtin_popcountll((x)) #define all(x) (x).begin(),(x).end() #define siz(x) (int)(x).size() #define forall(it,x) for(auto& it:(x)) using namespace __gnu_pbds; using namespace std; typedef tree<int, null_type, less<int>, rb_tree_tag,tree_order_statistics_node_update> ordered_set; //mt19937 mt;void random_start(){mt.seed(chrono::time_point_cast<chrono::milliseconds>(chrono::high_resolution_clock::now()).time_since_epoch().count());} //ll los(ll a, ll b) {return a + (mt() % (b-a+1));} const int INF = 1e9+50; const ll INF_L = 1e18+40; const ll MOD = 1e9+7; const int tree_siz = 1024*2048-1; ll drzewo[tree_siz]; ll spych_set[tree_siz]; ll spych_add[tree_siz]; void spych(int v) { if(spych_set[v-1] != -1e18) { drzewo[v*2-1] = spych_set[v-1]; drzewo[v*2] = spych_set[v-1]; spych_set[v*2-1] = spych_set[v-1]; spych_set[v*2] = spych_set[v-1]; spych_add[v*2-1] = 0; spych_add[v*2] = 0; spych_set[v-1] = -1e18; spych_add[v-1] = 0; } else { drzewo[v*2-1] += spych_add[v-1]; drzewo[v*2] += spych_add[v-1]; if(spych_set[v*2-1] == -1e18) { spych_add[v*2-1] += spych_add[v-1]; } else { spych_set[v*2-1] += spych_add[v-1]; } if(spych_set[v*2] == -1e18) { spych_add[v*2] += spych_add[v-1]; } else { spych_set[v*2] += spych_add[v-1]; } spych_add[v-1] = 0; } } void upd(int akt) { drzewo[akt-1] = max(drzewo[akt*2-1],drzewo[akt*2]); } void set_val(int akt, int p1, int p2, int s1, int s2, ll val) { if(p2 < s1 || p1 > s2) return; if(p1 >= s1 && p2 <= s2) { drzewo[akt-1] = val; spych_set[akt-1] = val; spych_add[akt-1] = 0; return; } spych(akt); set_val(akt*2,p1,(p1+p2)/2,s1,s2,val); set_val(akt*2+1,(p1+p2)/2+1,p2,s1,s2,val); upd(akt); } void add_val(int akt, int p1, int p2, int s1, int s2, ll val) { if(p2 < s1 || p1 > s2) return; if(p1 >= s1 && p2 <= s2) { drzewo[akt-1] += val; if(spych_set[akt-1] == -1e18) spych_add[akt-1] += val; else spych_set[akt-1] += val; return; } spych(akt); add_val(akt*2,p1,(p1+p2)/2,s1,s2,val); add_val(akt*2+1,(p1+p2)/2+1,p2,s1,s2,val); upd(akt); } ll get_val(int akt, int p1, int p2, int s1, int s2) { if(p2 < s1 || p1 > s2) return -1e18; if(p1 >= s1 && p2 <= s2) { return drzewo[akt-1]; } spych(akt); ll w1 = get_val(akt*2,p1,(p1+p2)/2,s1,s2); ll w2 = get_val(akt*2+1,(p1+p2)/2+1,p2,s1,s2); upd(akt); return max(w1,w2); } int poz_greater(int akt, int l, int r, ll x) { if(l == r) return l; spych(akt); if(drzewo[akt*2-1] >= x) return poz_greater(akt*2,l,(l+r)/2,x); return poz_greater(akt*2+1,(l+r)/2+1,r,x); } int find_greater(int akt, int p1, int p2, int s1, int s2, ll x) { if(p2 < s1 || p1 > s2) return -1; if(p1 >= s1 && p2 <= s2) { if(drzewo[akt-1] >= x) { return poz_greater(akt,p1,p2,x); } return -1; } spych(akt); int w1 = find_greater(akt*2,p1,(p1+p2)/2,s1,s2,x); if(w1 == -1) { w1 = find_greater(akt*2+1,(p1+p2)/2+1,p2,s1,s2,x); } upd(akt); return w1; } ll pref_sum[1000'001][2]; ll S[1000'001][2]; ll C[1000'001][2]; map<int,ll> events_map[1000'002]; vector<pll> events[1000'002]; ll def_ans; int main() { ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0); //random_start(); rep(i,tree_siz) { drzewo[i] = -1e18; spych_set[i] = -1e18; spych_add[i] = -1e18; } int n,m; cin >> n >> m; set_val(1,0,tree_siz/2,0,m,0); rep2(i,1,n) { ll a; cin >> a >> S[i][0] >> C[i][0]; pref_sum[i][0] = pref_sum[i-1][0] + a; } rep2(i,1,m) { ll a; cin >> a >> S[i][1] >> C[i][1]; pref_sum[i][1] = pref_sum[i-1][1] + a; } pref_sum[n+1][0] = pref_sum[n][0]; rep2(i,1,n) { int l = 0; int r = m; int ans = -1; while(l <= r) { int mid = (l+r)/2; if(pref_sum[mid][1] + pref_sum[i][0] <= S[i][0]) { ans = mid; l = mid+1; } else { r = mid-1; } } // cerr << i << " " << ans << " lim1\n"; if(ans != -1) { events_map[i][ans] += C[i][0]; } } rep2(i,1,m) { int l = 0; int r = n+1; int ans = -1; while(l <= r) { int mid = (l+r)/2; if(pref_sum[mid][0] + pref_sum[i][1] <= S[i][1]) { ans = mid; l = mid+1; } else { r = mid-1; } } // cerr << i << " " << ans << " lim2\n"; if(ans != -1) { def_ans += C[i][1]; events_map[ans+1][i-1] += -C[i][1]; } } rep2(i,0,n) { forall(it,events_map[i]) { events[i].pb({it.ff,it.ss}); } sort(all(events[i])); reverse(all(events[i])); } rep2(i,0,n) { sort(all(events[i])); reverse(all(events[i])); } rep2(i,0,n) { // cerr << i << " i:\n\n"; forall(it,events[i]) { //cerr << it.ff << " " << it.ss << " event!!!!\n"; add_val(1,0,tree_siz/2,0,it.ff,it.ss); ll new_pref_max = get_val(1,0,tree_siz/2,it.ff,it.ff); // cerr << new_pref_max << " new_max\n"; if(it.ff+1 <= m) { int pref = find_greater(1,0,tree_siz/2,it.ff+1,m,new_pref_max); // cerr << pref << " pref\n"; if(pref == -1) pref = m+1; // cerr << pref << " pref\n"; if(pref != it.ff+1) { set_val(1,0,tree_siz/2,it.ff+1,pref-1,new_pref_max); } } } // rep2(j,0,m) // { // cerr << get_val(1,0,tree_siz/2,j,j) << " "; // } // cerr << " dp\n"; } // cerr << def_ans << " def\n"; cout << def_ans + get_val(1,0,tree_siz/2,m,m) << "\n"; }
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...