/*
Ben Watson
Handle codeforces : quangminh98
Current Theme: Transformers !!!!
*/
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const string name = "test";
void solve();
signed main()
{
if (fopen((name + ".inp").c_str(), "r"))
{
freopen((name + ".inp").c_str(), "r", stdin);
freopen((name + ".out").c_str(), "w", stdout);
}
ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
solve();
return 0;
}
// main program
const int oo = 0x3f3f3f3f;
const int maxn = 3e5 + 1;
const int maxbit = 30;
const int N = 548;
struct SegmentTree
{
struct Node
{
int mn, lazy;
Node(int val) : mn(val), lazy(oo) {};
Node operator + (const Node& other)
{
Node res = Node(oo);
res.mn = min(mn, other.mn);
return res;
}
};
vector<Node> st;
int n;
SegmentTree(int n) : n(n) { st.resize(4 * n + 1, Node(oo)); }
void pass(int head, int l, int r)
{
if (st[head].lazy == oo)
return;
st[head].mn = min(st[head].mn, st[head].lazy);
if (l != r)
{
st[head << 1].lazy = min(st[head << 1].lazy, st[head].lazy);
st[head << 1 | 1].lazy = min(st[head << 1 | 1].lazy, st[head].lazy);
}
st[head].lazy = oo;
}
void update(int head, int l, int r, int u, int v, int val)
{
pass(head, l, r);
if (l > v || r < u) return;
if (u <= l && r <= v)
{
st[head].lazy = min(st[head].lazy, val);
pass(head, l, r);
return;
}
int mid = l + r >> 1;
update(head << 1, l, mid, u, v, val);
update(head << 1 | 1, mid + 1, r, u, v, val);
st[head] = st[head << 1] + st[head << 1 | 1];
}
void update(int u, int v, int val) { if (u > v) return; update(1, 1, n, u, v, val); }
int query(int head, int l, int r, int pos)
{
pass(head, l, r);
if (pos < l || r < pos) return oo;
if (l == r) return st[head].mn;
int mid = l + r >> 1;
if (pos <= mid)
return query(head << 1, l, mid, pos);
return query(head << 1 | 1, mid + 1, r, pos);
}
int query(int pos) { return query(1, 1, n, pos); }
};
struct Trie
{
struct Node
{
Node* child[2];
int mx;
Node() : mx(0) { for (int i = 0; i < 2; i++) child[i] = nullptr; }
};
Node* root;
Trie() { root = new Node(); }
void add(int x, int val)
{
Node* p = root;
for (int i = maxbit - 1; i >= 0; i--)
{
int bit = (x >> i & 1);
if (p->child[bit] == nullptr)
p->child[bit] = new Node();
p = p->child[bit];
p->mx = max(p->mx, val);
}
}
int query(int x) // > x
{
int res = 0;
Node* p = root;
for (int i = maxbit - 1; i >= 0; i--)
{
int bit = (x >> i & 1);
if (p->child[bit] == nullptr)
p->child[bit] = new Node();
if (bit == 0 && p->child[1] != nullptr)
res = max(res, p->child[1]->mx);
p = p->child[bit];
}
return res;
}
};
struct FenwickTree
{
vector<Trie> bits;
int n;
FenwickTree(int n) : n(n) { bits.resize(n + 1); }
void update(int pos, int cur, int val)
{
for (; pos <= n; pos += (pos & (-pos)))
bits[pos].add(cur, val);
}
int query(int pos, int x)
{
int res = 0;
for (; pos > 0; pos -= (pos & (-pos)))
res = max(res, bits[pos].query(x));
return res;
}
};
int n, d, cur, num;
int coor[maxn];
int block_id[maxn];
map<int, int> cmp;
int a[maxn], dp[maxn], R[maxn];
void solve()
{
cin >> n >> d;
cur = 0;
vector<int> v;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
v.push_back(a[i]);
}
// coordinate compression
sort(v.begin(), v.end());
cur = 0;
for (int x : v)
if (cmp[x] == 0)
cmp[x] = ++cur;
for (int i = 1; i <= n; i++)
coor[i] = cmp[a[i]];
// sqrt decomposition
num = 1;
for (int i = 1; i <= n; i++)
{
if ((i - 1) % N == 0)
num++;
block_id[i] = num;
}
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
SegmentTree st(cur);
for (int i = n; i > 0; i--)
{
R[i] = n;
pq.push({a[i], i});
while (!pq.empty() && pq.top().second >= i + d)
pq.pop();
if (i + d <= n)
R[i] = min(R[i], st.query(cmp[a[i]]));
if (i + d - 1 <= n)
st.update(1, cmp[pq.top().first] - 1, i + d - 1);
}
int res = 0;
FenwickTree bit(num);
for (int i = n; i > 0; i--)
{
int mx = 0;
if (block_id[R[i]] != 1)
mx = bit.query(block_id[R[i]] - 1, a[i]);
for (int j = R[i]; j > i && block_id[j] == block_id[R[i]]; j--)
if (a[j] > a[i])
mx = max(mx, dp[j]);
dp[i] = 1 + mx;
bit.update(block_id[i], a[i], dp[i]);
res = max(res, dp[i]);
}
cout << res << '\n';
}
Compilation message (stderr)
Main.cpp: In function 'int main()':
Main.cpp:20:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
20 | freopen((name + ".inp").c_str(), "r", stdin);
| ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Main.cpp:21:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
21 | freopen((name + ".out").c_str(), "w", stdout);
| ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# | 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... |