Submission #1181387

#TimeUsernameProblemLanguageResultExecution timeMemory
1181387catch_me_if_you_canRadio Towers (IOI22_towers)C++20
11 / 100
242 ms25028 KiB
//lurker you should listen to https://www.youtube.com/watch?v=a3egbaw-VK4 ASAP //Hofstadter's law: programming projects take longer than you expect, even when you take into account Hofstadter's law #include<bits/stdc++.h> #include "towers.h" using namespace std; #define in array<int, 2> #define pb push_back #define pob pop_back const int MX = 1e5+5; const int INF = 2e9; const int LOGM = 18; int n; vector<int> a(MX); vector<int> lo_w(MX); vector<int> hi_w(MX); vector<int> nxt_lo(MX);//next optimal descent. vector<int> nxt_hi(MX);//next optimal ascent. vector<int> clow(MX); int LO[LOGM][MX]; int HI[LOGM][MX]; int Nxt[LOGM][MX]; bool rinited = false; void init(int N, vector<int> h) { n = N; rinited = false; for(int i = 1; i <= n; i++) a[i] = h[i-1]; vector<int> lo(n+2);//immediate next dip vector<int> hi(n+2);//immediate next up //vector<int> lo_w(n+1);//suppose a[i], >a[i], >a[i] ..., < a[i]. largest "value" among the next few vals //vector<int> hi_w(n+1);//same as above, smallest value among the next few vals for(int i = 1; i <= n; i++) lo[i] = hi[i] = i+1; a[n+1] = -INF; LO[0][n] = LO[0][n+1] = n+1; for(int i = n; i >= 1; i--) { lo_w[i] = a[i]; while(a[lo[i]] > a[i]) { lo_w[i] = max(lo_w[i], lo_w[lo[i]]); lo[i] = lo[lo[i]]; } LO[0][i] = lo[i]; } a[n+1] = +INF; HI[0][n] = HI[0][n+1] = n+1; for(int i = n; i >= 1; i--) { hi_w[i] = a[i]; while(a[hi[i]] < a[i]) { hi_w[i] = min(hi_w[i], hi_w[hi[i]]); hi[i] = hi[hi[i]]; } HI[0][i] = hi[i]; } for(int i = 1; i <= n; i++) { lo_w[i] = lo_w[i] - a[i]; hi_w[i] = a[i] - hi_w[i]; } for(int k = 1; k < LOGM; k++) { for(int i = 1; i <= n+1; i++) LO[k][i] = LO[k-1][LO[k-1][i]]; for(int i = 1; i <= n+1; i++) HI[k][i] = HI[k-1][HI[k-1][i]]; } /*cout << "Debugging vals: " << endl; for(int i = 1; i <= n; i++) cout << lo_w[i] << " "; cout << endl; for(int i = 1; i <= n; i++) cout << hi_w[i] << " "; cout << endl;*/ return; } void r_init(int D) { if(rinited) return; rinited = true; vector<int> sp_lo(n+2, n+1); vector<int> sp_hi(n+2, n+1); clow.assign(n+2, n+1); for(int i = n; i >= 1; i--) { if(lo_w[i] >= D) sp_lo[i] = i; else sp_lo[i] = sp_lo[LO[0][i]]; clow[i] = sp_lo[i]; if(hi_w[i] >= D) sp_hi[i] = i; else sp_hi[i] = sp_hi[HI[0][i]]; } for(int i = 1; i <= n; i++) { //cout << "Currently computing optimal jumps for i = " << i << endl; int u = i; a[n+1] = INF; for(int k = LOGM-1; k >= 0; k--) { if(a[HI[k][u]] < (D+a[i])) u = HI[k][u]; } u = HI[0][u]; //cout << "First worker = " << u << endl; //now u is the smallest active fellow after i. int j = sp_hi[u]; //cout << "- First jump should go to " << j << endl; if(j == (n+1)) { Nxt[0][i] = n+1; continue; } a[n+1] = -INF; u = j; for(int k = LOGM-1; k >= 0; k--) { if(a[LO[k][u]] > (a[j]-D)) u = LO[k][u]; } u = LO[0][u]; //cout << "Ended at " << u << endl; int ip = sp_lo[u]; Nxt[0][i] = ip; if((ip) == (n+1)) Nxt[0][i] = u; //cout << "--- Next jump should go to " << Nxt[0][i] << endl; } Nxt[0][n+1] = n+1; for(int k = 1; k < LOGM; k++) { for(int i = 1; i <= (n+1); i++) { Nxt[k][i] = Nxt[k-1][Nxt[k-1][i]]; //cout << Nxt[k][i] << " "; } //cout << endl; } return; } int max_towers(int L, int R, int D) { L++; R++; r_init(D); if(clow[L] > R) return 1; int ans = 1; int u = clow[L]; //cout << "For optimal results, we should start at u = " << u << endl; for(int k = LOGM-1; k >= 0; k--) { if(Nxt[k][u] <= R) { u = Nxt[k][u]; //cout << "I jumped to " << u << endl; ans+=((1ll<<k)); } } return ans; }
#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...