이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include <bits/stdc++.h>
using namespace std;
const int MN = 2e5 + 5, MOD = 1e9 + 7, LOG = 17;
int dp[MN], bit[MN], to[MN], p[MN][LOG];
vector<int> withDp[MN];
void update (int i, int v) {
for (;i<MN;i+=i&-i)
bit[i] = max(bit[i],v);
}
int query (int i) {
int ret = 0;
for (;i>0;i^=i&-i)
ret = max(ret,bit[i]);
return ret;
}
vector<int> xs;
int getx (int x) {return lower_bound(xs.begin(),xs.end(),x) - xs.begin() + 1;}
int main () {
int n,k; scanf ("%d %d",&n,&k);
vector<array<int,3>> segs(n+1);
vector<array<int,2>> og(n+1);
for (int i = 1; i <= n; i++) {
auto &[l,r,idx] = segs[i];
idx = i;
scanf ("%d %d",&l,&r); og[i] = {l,r};
xs.push_back(l); xs.push_back(r);
}
xs.push_back(0); xs.push_back(MOD);
segs.push_back({0,0,n+1}); segs.push_back({MOD,MOD,n+2});
n += 2;
sort(xs.begin(),xs.end()); xs.erase(unique(xs.begin(),xs.end()),xs.end());
sort(segs.begin()+1,segs.end());
for (int i = 1; i <= n; i++) {
auto &[l,r,idx] = segs[i];
l = getx(l); r = getx(r); to[idx] = i;
dp[i] = query(l) + 1;
update(r,dp[i]);
withDp[dp[i]].push_back(i);
}
int mx = *max_element(dp+1,dp+1+n);
if (mx - 2 < k) return !printf ("-1\n");
auto get = [&] (int v, int x) { //l[i] >= x
int low = 0, high = (int)withDp[v].size() - 1, mid, ans = -1;
while (low <= high) {
mid = (low + high) / 2;
if (segs[withDp[v][mid]][0] >= x) high = (ans = mid) - 1;
else low = mid + 1;
}
return ~ans ? withDp[v][ans] : 0;
};
for (int v = mx-1; v >= 1; v--) {
int mn = 1e9;
for (int j = (int)withDp[v].size() - 1; j >= 0; j--) {
int i = withDp[v][j];
mn = min(mn,segs[i][1]);
p[i][0] = get(v+1,mn);
for (int j = 1; j < LOG; j++)
p[i][j] = p[p[i][j-1]][j-1];
}
}
auto pathLength = [&] (int i, int j) { //i < j, dp[i] < dp[j]
int ret = dp[j] - dp[i];
for (int k = 0; k < LOG; k++)
if (ret >> k & 1)
i = p[i][k];
return ret + (i > 0 && i <= j);
};
set<int> have = {1,n};
int cur = dp[n] - 2;
for (int j = 1; j <= n-2 && (int)have.size() < k + 2; j++) {
int i = to[j];
auto it = have.lower_bound(i);
int lst = *prev(it), nxt = *it;
if (segs[lst][1] > segs[i][0] || segs[i][1] > segs[nxt][0]) continue;
int oldGet = pathLength(lst,nxt);
int newGet = pathLength(lst,i) + pathLength(i,nxt) - 1;
if (cur - oldGet + newGet >= k) { //success
printf ("%d\n",j);
have.insert(i);
cur += newGet - oldGet;
}
}
return 0;
}
컴파일 시 표준 에러 (stderr) 메시지
event2.cpp: In function 'int main()':
event2.cpp:19:17: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
19 | int n,k; scanf ("%d %d",&n,&k);
| ~~~~~~^~~~~~~~~~~~~~~
event2.cpp:25:9: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
25 | scanf ("%d %d",&l,&r); og[i] = {l,r};
| ~~~~~~^~~~~~~~~~~~~~~
# | 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... |