이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
void debug_out(){cerr<<endl;}
template<typename Head, typename... Tail>
void debug_out(Head H, Tail... T){
cerr << H << ' ';
debug_out(T...);
}
#define debug(...) cerr << "(" << #__VA_ARGS__ << "): ", debug_out(__VA_ARGS__)
#define F first
#define S second
#define all(x) x.begin(), x.end()
#define MP(x, y) make_pair(x, y)
const int maxn = 3e5 + 10;
const int lg = 22;
struct Seg{
int l, r, ans;
bool b;
} seg[maxn*lg];
int n, d, a[maxn], dp[maxn], lc[maxn*lg], rc[maxn*lg], root[maxn], vercnt = 1;
vector<pii> val;
void build(int v, int l, int r){
seg[v].l = seg[v].r = seg[v].b = seg[v].ans = 0;
if (l + 1 == r){
return;
}
int mid = (l + r) >> 1;
lc[v] = vercnt++;
rc[v] = vercnt++;
build(lc[v], l, mid);
build(rc[v], mid, r);
}
Seg operator +(Seg a, Seg b){
Seg res;
res.l = (a.b? a.l + b.l: a.l);
res.r = (b.b? b.r + a.r: b.r);
res.ans = max({a.ans, b.ans, a.r + b.l});
res.b = (a.b && b.b);
return res;
}
void change(int v, int newv, int l, int r, int idx){
if (l + 1 == r){
seg[newv].l = seg[newv].r = seg[newv].ans = seg[newv].b = 1;
return;
}
int mid = (l + r) >> 1;
if (idx < mid){
lc[newv] = vercnt++;
rc[newv] = rc[v];
change(lc[v], lc[newv], l, mid, idx);
}
else{
lc[newv] = lc[v];
rc[newv] = vercnt++;
change(rc[v], rc[newv], mid, r, idx);
}
seg[newv] = seg[lc[newv]] + seg[rc[newv]];
}
Seg get(int v, int l, int r, int ql, int qr){
if (qr <= l || r <= ql){
Seg tmp;
tmp.l = tmp.r = tmp.ans = 0;
tmp.b = true;
return tmp;
}
if (ql <= l && r <= qr) return seg[v];
int mid = (l + r) >> 1;
return get(lc[v], l, mid, ql, qr)
+ get(rc[v], mid, r, ql, qr);
}
vector<int> num[maxn << 2];
vector<int> mx[maxn << 2];
bool ok[maxn << 2];
void add(int v, int l, int r, int idx){
if (idx < l || r <= idx) return;
if (l + 1 == r){
num[v].resize(1);
mx[v].resize(1);
num[v][0] = (a[idx]);
mx[v][0] = (dp[idx]);
ok[v] = true;
return;
}
int mid = (l + r) >> 1;
add(v << 1, l, mid, idx);
add(v << 1 | 1, mid, r, idx);
if (!ok[v<<1] || !ok[v<<1|1]) return;
ok[v] = true;
int ptl = 0, ptr = 0;
num[v].resize(r-l);
mx[v].resize(r-l);
for (int i = 0; i < r-l; i++){
if (ptr == num[v<<1|1].size() || (ptl != num[v << 1].size() && num[v<<1][ptl] < num[v<<1|1][ptr])){
num[v][i] = num[v<<1][ptl];
mx[v][i] = mx[v<<1][ptl];
ptl++;
}
else{
num[v][i] = num[v<<1|1][ptr];
mx[v][i] = mx[v<<1|1][ptr];
ptr++;
}
}
for (int i = 1; i < r-l; i++){
mx[v][i] = max(mx[v][i], mx[v][i-1]);
}
}
int get(int v, int l, int r, int ql, int qr, int val){
if (qr <= l || r <= ql) return 0;
if (ql <= l && r <= qr && ok[v]){
int idx = lower_bound(all(num[v]), val) - num[v].begin();
if (idx != 0) return mx[v][idx-1];
return 0;
}
int mid = (l + r) >> 1;
return max(get(v << 1, l, mid, ql, qr, val)
,get(v << 1 | 1, mid, r, ql, qr, val));
}
int main(){
cin >> n >> d;
for (int i = 1; i <= n; i++){
cin >> a[i];
val.push_back({a[i], i});
}
sort(all(val));
root[n] = 0;
build(0, 1, n+1);
//debug(vercnt);
for (int i = n-1; ~i; i--){
root[i] = vercnt++;
//debug(i, val[i].S);
change(root[i+1], root[i], 1, n+1, val[i].S);
//debug(vercnt);
}
int ans = 0;
for (int i = 1; i <= n; i++){
int idx = lower_bound(all(val), MP(a[i], 0)) - val.begin();
//debug(i, idx);
int l = 0, r = i;
while (l + 1 < r){
int mid = (l + r) >> 1;
// debug(mid, get(root[idx], 1, n+1, mid, i).ans);
if (get(root[idx], 1, n+1, mid, i).ans < d) r = mid;
else l = mid;
}
// debug(r);
dp[i] = get(1, 1, n+1, r, i, a[i]) + 1;
// debug(i, dp[i]);
add(1, 1, n+1, i);
ans = max(ans, dp[i]);
}
// debug(vercnt);
cout << ans << '\n';
return 0;
}
컴파일 시 표준 에러 (stderr) 메시지
Main.cpp: In function 'void build(int, int, int)':
Main.cpp:33:46: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
33 | seg[v].l = seg[v].r = seg[v].b = seg[v].ans = 0;
| ~~~~~~~~~~~^~~
Main.cpp: In function 'void add(int, int, int, int)':
Main.cpp:108:11: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
108 | if (ptr == num[v<<1|1].size() || (ptl != num[v << 1].size() && num[v<<1][ptl] < num[v<<1|1][ptr])){
| ~~~~^~~~~~~~~~~~~~~~~~~~~
Main.cpp:108:41: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
108 | if (ptr == num[v<<1|1].size() || (ptl != num[v << 1].size() && num[v<<1][ptl] < num[v<<1|1][ptr])){
| ~~~~^~~~~~~~~~~~~~~~~~~~~
# | 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... |