P7562 [JOISC 2021] イベント巡り 2 (Event Hopping 2) (Day4)
Sol
直接一位一位贪,判断贪完之后是否能放满 \(k\) 个即可。
这个东西我们只需要维护一个区间里面最多能取几个,然后 set 维护当前没选的段即可。
Code
#include <bits/stdc++.h>
#define x first
#define y second
#define pb push_back
#define pf push_front
#define desktop "C:\\Users\\incra\\Desktop\\"
#define IOS ios :: sync_with_stdio (false),cin.tie (0),cout.tie (0)
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair <int,int> PII;
const int dx[] = {1,0,-1,0},dy[] = {0,-1,0,1};
template <typename T1,typename T2> bool tomax (T1 &x,T2 y) {
if (y > x) return x = y,true;
return false;
}
template <typename T1,typename T2> bool tomin (T1 &x,T2 y) {
if (y < x) return x = y,true;
return false;
}
LL power (LL a,LL b,LL p) {
LL ans = 1;
while (b) {
if (b & 1) ans = ans * a % p;
a = a * a % p;
b >>= 1;
}
return ans;
}
int fastio = (IOS,0);
#define endl '\n'
#define puts(s) cout << (s) << endl
const int N = 200010,MAX_LOG = 20;
int n,k;
int l[N],r[N];
int f[N][MAX_LOG];
int query (int l,int r) {
if (l > r) return 0;
int ans = 0;
int p = l;
for (int i = MAX_LOG - 1;i >= 0;i--) {
if (f[p][i] <= r) {
p = f[p][i] + 1;
ans += 1 << i;
}
}
return ans;
}
void mian () {
cin >> n >> k;
vector <double> all;
for (int i = 1;i <= n;i++) cin >> l[i] >> r[i],all.pb (l[i] + 0.1),all.pb (r[i] - 0.1);
sort (all.begin (),all.end ());
all.erase (unique (all.begin (),all.end ()),all.end ());
int m = all.size ();
auto find = [&](double x) {
return lower_bound (all.begin (),all.end (),x) - all.begin () + 1;
};
memset (f,0x3f,sizeof (f));
for (int i = 1;i <= n;i++) l[i] = find (l[i] + 0.1),r[i] = find (r[i] - 0.1),tomin (f[l[i]][0],r[i]);
for (int i = m;i >= 1;i--) tomin (f[i][0],f[i + 1][0]);
for (int j = 1;j < MAX_LOG;j++) {
for (int i = 1;i <= m;i++) {
if (f[i][j - 1] <= m) tomin (f[i][j],f[f[i][j - 1] + 1][j - 1]);
}
}
if (query (1,m) < k) {
puts ("-1");
return ;
}
set <PII> s;
s.insert ({1,m});
vector <int> ans;
int tmp = query (1,m);
for (int i = 1;i <= n;i++) {
if (ans.size () == k) break;
if (s.begin () -> x > l[i]) continue;
auto it = --s.upper_bound ({l[i],(int)1e9});
// cout << i << ' ' << l[i] << ' ' << r[i] << " " << it -> x << ' ' << it -> y << " " << next (it) -> x << ' ' << next (it) -> y << endl;
if (it -> x <= l[i] && r[i] <= it -> y) {
int ntmp = tmp - query (it -> x,it -> y) + query (it -> x,l[i] - 1) + query (r[i] + 1,it -> y) + 1;
if (ntmp >= k) {
tmp = ntmp;
ans.pb (i);
auto _ = *it;
s.erase (it);
if (_.x <= l[i] - 1) s.insert ({_.x,l[i] - 1});
if (r[i] + 1 <= _.y) s.insert ({r[i] + 1,_.y});
}
}
}
for (int x : ans) cout << x << endl;
}
int main () {
int T = 1;
// cin >> T;
while (T--) mian ();
return 0;
}

浙公网安备 33010602011771号