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 <atcoder/maxflow.hpp>
//#include <ext/pb_ds/assoc_container.hpp>
//#include <ext/pb_ds/tree_policy.hpp>
#include <iostream>
#include <map>
#include <list>
#include <set>
#include <algorithm>
#include <vector>
#include <string>
#include <functional>
#include <queue>
#include <deque>
#include <stack>
#include <unordered_map>
#include <unordered_set>
#include <cmath>
#include <iterator>
#include <random>
#include <chrono>
#include <complex>
#include <bitset>
#include <fstream>
#define forr(i,start,count) for (int i = (start); i < (start)+(count); ++i)
#define set_map_includes(set, elt) (set.find((elt)) != set.end())
#define readint(i) int i; cin >> i
#define readll(i) ll i; cin >> i
#define readdouble(i) double i; cin >> i
#define readstring(s) string s; cin >> s
typedef long long ll;
//using namespace __gnu_pbds;
//using namespace atcoder;
using namespace std;
const ll modd = (1000LL * 1000LL * 1000LL + 7LL);
//const ll modd = 998244353;
template<class T>
class SegmentTree2 {
public:
SegmentTree2(const vector<T>& data, function<T(T,T)> f_, T zero_value = 0) : zv(zero_value), f(f_) {
Initialize(data);
}
SegmentTree2(int n, function<T(T,T)> f_, T zero_value = 0) : zv(zero_value), f(f_) {
vector<T> temp(n, zv);
Initialize(temp);
}
T operator[](int i) {
return tree[B+i];
}
T GetEvaluation(int L, int R) { // "min/max" on interval [L,R); 0-based indexing, as usual
if (R<=L) { return zv; }
return GetEvaluationHelper(L, R, 0, B, 1);
}
void SetVal(int i, T val) {
tree[B+i] = val;
for(int j = (B + i) / 2; j >= 1; j /= 2) {
tree[j] = f(tree[2*j], tree[2*j+1]);
}
}
private:
vector<T> tree;
int B; // power of two greater than size of input data
T zv;
function<T(T,T)> f;
void Initialize(const vector<T>& data) {
B = 1;
while(B < data.size()) {B *= 2; }
tree = std::move(vector<T>(2*B, zv));
copy(data.begin(), data.end(), next(tree.begin(), B));
for(int i = B - 1; i >= 1; --i) {
tree[i] = f(tree[2*i], tree[2*i+1]);
}
}
T GetEvaluationHelper(int L, int R, int start, int length, int tree_index) {
if (L==R) { return zv; }
if ((L==start) && (R==start+length)) { return tree[tree_index]; }
int midpoint = start + length/2;
T left_ = zv, right_ = zv;
if (L<=min(midpoint,R)) {
left_ = GetEvaluationHelper(L, min(midpoint,R), start, length/2, 2*tree_index);
}
if (max(midpoint,L)<=R) {
right_ = GetEvaluationHelper(max(midpoint,L), R, midpoint, length/2, 2*tree_index+1);
}
return f(left_, right_);
}
};
class block_correct {
public:
vector<bool> occupied;
int dd;
block_correct(int n, int d) : occupied(n, false), dd(d) {}
void print() {
for(auto x : occupied) {
cout << (x ? "1" : "0");
}
cout << endl;
}
void add(int i) {
occupied[i] = true;
}
int upto(int i) {
forr(j,i,occupied.size()) {
if (j+dd>occupied.size()) { break; }
bool occ = true;
forr(k,j,dd) {
occ &= occupied[k];
}
if (occ) {
return j+dd;
}
}
return occupied.size();
}
};
class block {
public:
set<pair<int,int>> intervals;
set<int> obstacle_begin;
int d;
int n;
block(int nn, int dd) : n(nn), d(dd) {}
void print() {
for(auto x : intervals) {
cout << x.first << "," << x.second << "; ";
}
cout << "!!";
cout << endl;
}
void add(int i) {
auto it = intervals.lower_bound(make_pair(i,i));
bool merge_right = ((it!=intervals.end()) && (it->first==i+1));
bool merge_left = ((it!=intervals.begin()) && (prev(it)->second==i));
if ((!merge_left) && (!merge_right)) {
intervals.insert(make_pair(i, i+1));
if (1>=d) obstacle_begin.insert(i);
}
if ((!merge_left) && (merge_right)) {
int r = it->second;
intervals.erase(it);
intervals.insert(make_pair(i, r));
if (r-i>=d) obstacle_begin.insert(i);
}
if ((merge_left) && (!merge_right)) {
int l = prev(it)->first;
intervals.erase(prev(it));
intervals.insert(make_pair(l, i+1));
if (i+1-l>=d) obstacle_begin.insert(l);
}
if ((merge_left) && (merge_right)) {
int l = prev(it)->first;
int r = it->second;
it = intervals.erase(it);
intervals.erase(prev(it));
intervals.insert(make_pair(l, r));
if (r-l>=d) obstacle_begin.insert(l);
}
}
int upto(int i) {
auto it = obstacle_begin.lower_bound(i);
if (it==obstacle_begin.end()) { return n; }
return *it+d;
}
};
int main(int argc, char *argv[]) {
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
uniform_int_distribution<int> rand_gen(0, modd); // rand_gen(rng) gets the rand no
ios_base::sync_with_stdio(false);
cin.tie(0);
cout.precision(12);
// readint(test_cases);
int test_cases = 1;
forr(t, 1, test_cases) {
readint(n); readint(d);
vector<int> ans(n);
map<int, vector<int>> vals;
forr(i,0,n) {
readint(aa);
vals[aa].push_back(i);
}
block bl(n, d);
int ret = 0;
SegmentTree2<int> seg_tree(n, [](int x, int y){ return max(x,y); }, 0);
auto it = vals.end();
while (it!=vals.begin()) {
--it;
for(int j : it->second) {
int val = 1 + seg_tree.GetEvaluation(j+1, bl.upto(j+1));
bl.add(j);
seg_tree.SetVal(j, val);
ret = max(ret, val);
}
}
cout << ret << endl;
}
return 0;
}
Compilation message (stderr)
Main.cpp: In member function 'int block_correct::upto(int)':
Main.cpp:29:53: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<bool>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
29 | #define forr(i,start,count) for (int i = (start); i < (start)+(count); ++i)
| ^
Main.cpp:129:11: note: in expansion of macro 'forr'
129 | forr(j,i,occupied.size()) {
| ^~~~
Main.cpp:130:23: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<bool>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
130 | if (j+dd>occupied.size()) { break; }
| ~~~~^~~~~~~~~~~~~~~~
Main.cpp: In constructor 'block::block(int, int)':
Main.cpp:149:11: warning: 'block::n' will be initialized after [-Wreorder]
149 | int n;
| ^
Main.cpp:148:11: warning: 'int block::d' [-Wreorder]
148 | int d;
| ^
Main.cpp:151:7: warning: when initialized here [-Wreorder]
151 | block(int nn, int dd) : n(nn), d(dd) {}
| ^~~~~
Main.cpp: In instantiation of 'void SegmentTree2<T>::Initialize(const std::vector<_Tp>&) [with T = int]':
Main.cpp:56:11: required from 'SegmentTree2<T>::SegmentTree2(int, std::function<T(T, T)>, T) [with T = int]'
Main.cpp:222:78: required from here
Main.cpp:84:19: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
84 | while(B < data.size()) {B *= 2; }
| ~~^~~~~~~~~~~~~
# | 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... |