제출 #534326

#제출 시각아이디문제언어결과실행 시간메모리
534326ac2hu무제 (POI11_tem)C++14
50 / 100
205 ms25960 KiB
#include <bits/stdc++.h> #ifdef DEBUG #include "../templates/debug.h" #else #define deb(x...) #endif using namespace std; const int N = 1e6 + 10; int L[N],R[N]; int leftmost[N]; char in[(1 << 23)]; template<typename T> struct rmq { int n; static const int b = 30; // block size vector<int> mask, t; // mask and sparse table int op(int x, int y) { return L[x] > L[y] ? x : y; } // least significant set bit int lsb(int x) { return x & -x; } // index of the most significant set bit int msb_index(int x) { return __builtin_clz(1)-__builtin_clz(x); } // answer query of v[r-size+1..r] using the masks, given size <= b int small(int r, int size = b) { // get only 'size' least significant bits of the mask // and then get the index of the msb of that int dist_from_r = msb_index(mask[r] & ((1<<size)-1)); return r - dist_from_r; } rmq(int n) : n(n), mask(n), t(n) { int curr_mask = 0; for (int i = 0; i < n; i++) { // shift mask by 1, keeping only the 'b' least significant bits curr_mask = (curr_mask<<1) & ((1<<b)-1); while (curr_mask > 0 and op(i, i - msb_index(lsb(curr_mask))) == i) { // current value is smaller than the value represented by the // last 1 in curr_mask, so we need to turn off that bit curr_mask ^= lsb(curr_mask); } // append extra 1 to the mask curr_mask |= 1; mask[i] = curr_mask; } // build sparse table over the n/b blocks // the sparse table is linearized, so what would be at // table[j][i] is stored in table[(n/b)*j + i] for (int i = 0; i < n/b; i++) t[i] = small(b*i+b-1); for (int j = 1; (1<<j) <= n/b; j++) for (int i = 0; i+(1<<j) <= n/b; i++) t[n/b*j+i] = op(t[n/b*(j-1)+i], t[n/b*(j-1)+i+(1<<(j-1))]); } // query(l, r) returns the actual minimum of v[l..r] // to get the index, just change the first and last lines of the function T query(int l, int r) { // query too small if (r-l+1 <= b) return L[small(r, r-l+1)]; // get the minimum of the endpoints // (there is no problem if the ranges overlap with the sparse table query) int ans = op(small(l+b-1), small(r)); // 'x' and 'y' are the blocks we need to query over int x = l/b+1, y = r/b-1; if (x <= y) { int j = msb_index(y-x+1); ans = op(ans, op(t[n/b*j+x], t[n/b*j+y-(1<<j)+1])); } return L[ans]; } }; struct scanner { char const* o; scanner(): o(in){ load(); } void load(){ in[ fread(in , 1, sizeof(in)- 4, stdin)] = 0; } long long readInt(){ unsigned long long u = 0, s = 0; while(*o && *o <= 32)++o; if (*o == '-')s = ~s, ++o; else if (*o == '+')++o; while(*o >='0' && *o <='9') u = (u << 3) + (u << 1) + (*o++ - '0'); return (u^s) + !!s; } }; signed main() { iostream::sync_with_stdio(false); cin.tie(nullptr);cout.tie(nullptr); scanner sc; int n = sc.readInt(); for(int i = 0;i<n;i++){ L[i] = sc.readInt(); R[i] = sc.readInt(); } rmq<int> rq(n); for(int i =0;i<n;i++){ int l = 0,r = i; while(l < r){ int mid = (l + r)/2; if(rq.query(mid,i) <= R[i]) r = mid; else l = mid + 1; } leftmost[i] = l; } for(int i = 1;i<n;i++) leftmost[i] = max(leftmost[i], leftmost[i - 1]); int mx= 0 ; for(int i = 0;i<n;i++){ mx = max(mx, i - leftmost[i] + 1); } cout << mx << "\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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...