This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include "bits/stdc++.h"
#define st first
#define nd second
using lint = int64_t;
constexpr int MOD = int(1e9) + 7;
constexpr int INF = 0x3f3f3f3f;
constexpr int NINF = 0xcfcfcfcf;
constexpr lint LINF = 0x3f3f3f3f3f3f3f3f;
const long double PI = acosl(-1.0);
// Returns -1 if a < b, 0 if a = b and 1 if a > b.
int cmp_double(double a, double b = 0, double eps = 1e-9) {
return a + eps > b ? b + eps > a ? 0 : 1 : -1;
}
using namespace std;
struct UF {
vector<int> e, mini;
UF(int n) : e(n, -1), mini(n) {
iota(mini.begin(), mini.end(), 0);
}
bool same_set(int a, int b) { return find(a) == find(b); }
int size(int x) { return -e[find(x)]; }
int find(int x) { return e[x] < 0 ? x : e[x] = find(e[x]); }
int minimum(int x){ return mini[find(x)]; }
bool unite(int a, int b) {
a = find(a), b = find(b);
if (a == b) return 0;
if (e[a] > e[b]) swap(a, b);
e[a] += e[b]; e[b] = a;
mini[a] = min(mini[a], mini[b]);
return 1;
}
};
struct segtree{
vector<int> tree;
segtree(int n) : tree(4*n + 1, -1) {};
int query(int l, int r, int id, int lq, int rq){
if(rq <= l || r <= lq) return -1;
if(lq <= l && r <= rq) return tree[id];
int mid = (l+r)/2;
return max(query(l, mid, 2*id, lq, rq), query(mid, r, 2*id + 1, lq, rq));
}
void update(int l, int r, int id, int x, int val){
if(x < l || x >= r) return;
if(l + 1 == r){
tree[id] = val;
return;
}
int mid = (l+r)/2;
update(l, mid, 2*id, x, val);
update(mid, r, 2*id + 1, x, val);
tree[id] = max(tree[2*id], tree[2*id+1]);
}
int query(int l, int r){
return query(0, int(tree.size()/4), 1, l, r);
}
void update(int x, int val){
update(0, int(tree.size()/4), 1, x, val);
}
};
int main() {
cin.tie(nullptr)->sync_with_stdio(false);
int n, d;
cin>>n>>d;
UF uf(n+1);
segtree seg(n+1);
vector<int> a(n+1);
vector<int> dp(n+1, -1);
dp[0] = 0;
seg.update(0, 0);
//dp[i] <-- max se i é o último e i > atrás
map<int,vector<int>> idOfVal;
for(int i=1; i<=n; i++){
cin>>a[i];
idOfVal[a[i]].push_back(i);
}
set<int> visited;
visited.insert(0);
for(auto &[x, ids]: idOfVal){
reverse(ids.begin(), ids.end());
for(int id: ids){
auto nxt = visited.upper_bound(id);
if(nxt != visited.end()){
if((*nxt) - id <= d)
uf.unite(id, *nxt);
}
if(nxt != visited.begin()){
auto before = nxt;
before--;
if(id - (*before) <= d)
uf.unite(id, *before);
}
visited.insert(id);
int l = uf.minimum(id);
dp[id] = 1 + max(0, seg.query(l, id));
seg.update(id, dp[id]);
}
}
cout<<*max_element(dp.begin(), dp.end())<<"\n";
//j > max before
return 0;
}
/*
[ ]Leu o problema certo???
[ ]Ver se precisa de long long
[ ]Viu o limite dos fors (é n? é m?)
[ ]Tamanho do vetor, será que é 2e5 em vez de 1e5??
[ ]Testar sample
[ ]Testar casos de borda
[ ]1LL no 1LL << i
[ ]Testar mod (é 1e9+7, mesmo?, será que o mod não ficou negativo?)
*/
# | 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... |