이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include <bits/stdc++.h>
#define all(x) x.begin(), x.end()
#define sz(x) (int) x.size()
#define endl '\n'
#define pb push_back
#define _ ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define int ll
using namespace std;
using ll = long long;
using ull = unsigned long long;
using ii = pair<int,int>;
using iii = tuple<int,int,int>;
const int inf = 2e9+1;
const int mod = 1e9+7;
const int maxn = 3e5+100;
template<typename X, typename Y> bool ckmin(X& x, const Y& y) { return (y < x) ? (x=y,1):0; }
template<typename X, typename Y> bool ckmax(X& x, const Y& y) { return (x < y) ? (x=y,1):0; }
ii seg[4*maxn];
int n, d;
vector<int> events[maxn];
int lis[4*maxn];
void update(int i, int l, int r, int x, int k) {
if (r < x || x < l) return;
if (l == r) {
seg[i] = {k, l}; return;
}
int md = (l + r) / 2;
update(2*i, l, md, x, k), update(2*i+1, md+1, r, x, k);
if (seg[2*i].first >= d) seg[i] = seg[2*i];
else seg[i] = max(seg[2*i], seg[2*i+1]);
}
ii query(int i, int l, int r, int x, int y = n) {
if (r < x || y < l) return {0, 0};
if (x <= l && r <= y) return seg[i];
int md = (l + r) / 2;
ii lx = query(2*i, l, md, x, y), rx = query(2*i+1, md+1, r, x, y);
if (lx.first >= d) return lx;
return max(lx, rx);
}
void upd(int i, int l, int r, int x, int k) {
if (x < l || r < x) return;
if (l == r) {
lis[i] = k; return;
}
int md = (l + r) / 2;
upd(2*i, l, md, x, k), upd(2*i+1, md+1, r, x, k);
lis[i] = max(lis[2*i], lis[2*i+1]);
}
int queryLis(int i, int l, int r, int x, int y) {
if (r < x || y < l || x > y) return 0;
if (x <= l && r <= y) return lis[i];
int md = (l + r) / 2;
return max(queryLis(2*i, l, md, x, y), queryLis(2*i+1, md+1, r, x, y));
}
int32_t main(){_
cin >> n >> d;
vector<int> v(n+1);
for (int i = 0; i < n; ++i) cin >> v[i];
vector<int> ord(n); iota(all(ord), 0);
sort(all(ord), [&] (int x, int y) {return (v[x] == v[y] ? x > y : v[x] < v[y]);});
ord.pb(n);
set<int> inserted;
vector<int> equal;
int cur = v[ord[0]];
for (auto id : ord) {
id++;
if (v[id - 1] != cur) {
for (auto x : equal) {
ii q = query(1, 1, n, x);
if (q.first >= d) {
// cout << x << " vai ser removido em " << q.second + d + 1 << endl;
events[q.second + d + 1].pb(x);
}
}
cur = v[id - 1], equal = {id};
} else equal.pb(id);
if (id == n + 1) break;
auto it = inserted.lower_bound(id);
if (it != begin(inserted)) {
it = prev(it);
int y = *it;
update(1, 1, n, y, id - y - 1), it = next(it);
}
int z;
if (it == end(inserted)) z = n - id;
else z = *it - id - 1;
update(1, 1, n, id, z), inserted.insert(id);
}
for (int i = 0; i < n; ++i) v[ord[i]] = i + 1;
int ans = 0;
for (int i = 1; i <= n; ++i) {
for (auto x : events[i]) {
// cout << "- " << x << endl;
upd(1, 1, n, v[x-1], 0);
}
int best = queryLis(1, 1, n, 1, v[i-1] - 1) + 1;
ckmax(ans, best);
// cout << "answer for " << i << ": " << best << endl;
upd(1, 1, n, v[i-1], best);
// cout << "+ " << i << ' ' << v[i-1] << ' ' << best << endl;
}
cout << ans << endl;
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |