มีจักรวาลอยู่ จักรวาล และมี Crystal อัน
แต่ละอันมี
ต้องเก็บ Crystal เรียงตาม
ขณะที่อยู่ในจักรวาล สามารถทำได้ 1 อย่าง จาก 2 operations
โจทย์: หาว่าเก็บ Crystal ได้มากสุดเท่าไร
เราสามารถสังเกตเห็นได้ว่าถ้า แล้ว sort Crystal ด้วย จากน้อยไปมาก จะเห็นได้ว่าเป็นโจทย์หาความยาว LIS ธรรมดา
ดังนั้นเราควรมี array ที่มีการ sort Crystal ด้วย จากน้อยไปมากแล้วทำ Sweepline ไปตามแต่ละตัวของ
(หลังจากนี้การพูดถึง Crystal ที่ หมายถึง Crystal ที่ ของ array )
สมมติว่าเราอยากเก็บ Crystal ที่ มี 2 case คือ
พิจารณา case ที่ 1 จะได้ว่าต้องหาจำนวน Crystal มากที่สุด(ให้ แทนค่านี้)โดยที่ Crystal ล่าสุดก่อนที่เราเก็บ Crystal อยู่จักรวาลเดียวกันกับ Crystal และ Crystal นั้นมีค่า
พิจารณา case ที่ 2 จะได้ว่าต้องหาจำนวน Crystal มากที่สุด(ให้ แทนค่านี้)โดยที่ Crystal ล่าสุดก่อนที่เราเก็บ Crystal อยู่คนละจักรวาลเดียวกันกับ Crystal และ Crystal นั้นมีค่า
จะได้ว่า ถ้าเราอยากเก็บ Crystal ที่ จะเก็บได้มากสุดคือ +1
เห็นได้ว่านี่ก็คือโจทย์ LIS โดยเราจะใช้ Fenwick tree เป็น data structure นี้ในการทำ LIS (ถ้าไม่รู้วิธีทำให้ลองศึกษาจากบทความนี้ Longest Increasing Subsequence using BIT
note: ในบทความนี้จะใช้ coordinate compression ด้วยซึ่งเป็นสิ่งที่เราจำเป็นต้องใช้)
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int mod = 1e9 + 7;
const int inf = 1e18;
const int N = 1e5 + 5;
const int U = 1e3 + 5;
int u, k, n, ans;
map<int, int> com;
set<int> ins;
tuple<int, int, int> a[N]; // {t, w, p}
struct Fenwick {
int fw[N];
void update(int idx, int val) {
while (idx < N) {
fw[idx] = max(fw[idx], val);
idx += idx & -idx;
}
}
int query(int idx) {
int res = 0;
while (idx > 0) {
res = max(res, fw[idx]);
idx -= idx & -idx;
}
return res;
}
} fenwick[U];
int32_t main() {
cin.tie(NULL)->sync_with_stdio(false);
cin >> u >> k >> n;
for (int i = 1; i <= n; i++) {
auto& [t, w, p] = a[i];
cin >> p >> w >> t;
ins.emplace(p);
}
vector<int> temp(ins.begin(), ins.end());
for (size_t i = 0; i < temp.size(); i++) {
com[temp[i]] = i + 1;
}
sort(a + 1, a + 1 + n);
for (int i = 1; i <= n; i++) {
auto [t, w, pp] = a[i];
int p = com[pp];
int x1 = fenwick[w].query(p - 1) + 1;
int x2 = fenwick[U - 1].query(p - 1) + 1 - k;
int x = max(x1, x2);
fenwick[U - 1].update(p, x);
fenwick[w].update(p, x);
ans = max(ans, x);
}
cout << ans << "\n";
return 0;
}
หากมีข้อสงสัย comment ไว้ใต้ post ได้เลยนะครับ 🙇♂️🙇♂️
ศึกษาโจทย์เพิ่มเติมได้ที่ Fast X Fourier