Submission #770543

#TimeUsernameProblemLanguageResultExecution timeMemory
770543parsadox2LIS (INOI20_lis)C++11
100 / 100
1917 ms163516 KiB
#include <bits/stdc++.h> #define pb push_back #define F first #define S second #define debug(x) cout << #x << "= " << x << ", " #define ll long long #define fast ios::sync_with_stdio(false), cin.tie(0), cout.tie(0) #define SZ(x) (int) x.size() #define wall cout << endl; using namespace std; mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()); const int maxn = 1e6 + 10; int q , ar[maxn] , val[maxn] , ans , fbi[maxn]; vector <pair<int , int>> query; set <int> st[maxn]; struct nod{ pair<int , int> mn; int lzy; } tree[maxn << 2]; void Build(int node = 1 , int nl = 0 , int nr = q) { tree[node].lzy = 0; if(nl + 1 == nr) { tree[node].mn.F = ar[nl]; tree[node].mn.S = -nl; return; } int mid = (nl + nr) >> 1 , lc = node << 1 , rc = lc | 1; Build(lc , nl , mid); Build(rc , mid , nr); tree[node].mn = min(tree[lc].mn , tree[rc].mn); } void uplzy(int node , int lc , int rc) { if(tree[node].lzy == 0) return; tree[lc].lzy += tree[node].lzy; tree[rc].lzy += tree[node].lzy; tree[lc].mn.F += tree[node].lzy; tree[rc].mn.F += tree[node].lzy; tree[node].lzy = 0; } void Rem(int pos , int node = 1 , int nl = 0 , int nr = q) { if(nl + 1 == nr) { tree[node].mn.F = maxn; return; } int mid = (nl + nr) >> 1 , lc = node << 1 , rc = lc | 1; uplzy(node , lc , rc); if(pos < mid) Rem(pos , lc , nl , mid); else Rem(pos , rc , mid , nr); tree[node].mn = min(tree[lc].mn , tree[rc].mn); } void Add(int pos , int node = 1 , int nl = 0 , int nr = q) { if(nr <= pos) return; if(nl >= pos) { tree[node].mn.F--; tree[node].lzy--; return; } int mid = (nl + nr) >> 1 , lc = node << 1 , rc = lc | 1; Add(pos , lc , nl , mid); Add(pos , rc , mid , nr); tree[node].mn = min(tree[rc].mn , tree[lc].mn); } void add(int pos , int ind) { if(st[ind].empty()) { st[ind].insert(pos); ans = ind; return; } auto it = st[ind].end(); it--; if(*st[ind].begin() < pos) { if(*it > pos) { it = st[ind].upper_bound(pos); it--; } if(ar[*it] < ar[pos]) { add(pos , ind + 1); return; } it++; } else { it = st[ind].begin(); } vector <int> vec; while(it != st[ind].end()) { int now = *it; if(ar[now] <= ar[pos]) break; it++; vec.pb(now); } for(auto u : vec) { st[ind].erase(u); add(u , ind + 1); } st[ind].insert(pos); } int32_t main() { fast; cin >> q; for(int i = 0 ; i < q ; i++) cin >> ar[i] >> val[i]; Build(); for(int i = 1 ; i <= q ; i++) { int pos = -tree[1].mn.S; fbi[pos] = i; ar[i] = val[pos]; Rem(pos); Add(pos); } st[0].insert(0); for(int i = 0 ; i < q ; i++) { add(fbi[i] , 1); cout << ans << '\n'; } return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...