제출 #1241974

#제출 시각아이디문제언어결과실행 시간메모리
1241974orzorzorzGlobal Warming (CEOI18_glo)C++20
100 / 100
339 ms38804 KiB
#include <iostream> #include <vector> #include <algorithm> #include <map> using namespace std; const int INF = 2e9; // 計算 LIS 的輔助函式 // 傳入一個數組,返回一個向量,其中 result[i] 是以原數組第 i 個元素結尾的 LIS 長度 vector<int> get_lis_lengths(const vector<int>& arr) { if (arr.empty()) { return {}; } int n = arr.size(); vector<int> result(n); vector<int> dp; // dp[i] 存儲長度為 i+1 的 LIS 的最小結尾元素 for (int i = 0; i < n; ++i) { auto it = lower_bound(dp.begin(), dp.end(), arr[i]); result[i] = (it - dp.begin()) + 1; if (it == dp.end()) { dp.push_back(arr[i]); } else { *it = arr[i]; } } return result; } // 線段樹結構,用於區間最大值查詢 vector<int> seg_tree; int seg_tree_size; void update_seg_tree(int idx, int val, int x, int lx, int rx) { if (rx - lx == 1) { seg_tree[x] = max(seg_tree[x], val); return; } int m = (lx + rx) / 2; if (idx < m) { update_seg_tree(idx, val, 2 * x + 1, lx, m); } else { update_seg_tree(idx, val, 2 * x + 2, m, rx); } seg_tree[x] = max(seg_tree[2 * x + 1], seg_tree[2 * x + 2]); } int query_seg_tree(int l, int r, int x, int lx, int rx) { if (lx >= r || l >= rx) return 0; if (lx >= l && rx <= r) return seg_tree[x]; int m = (lx + rx) / 2; int s1 = query_seg_tree(l, r, 2 * x + 1, lx, m); int s2 = query_seg_tree(l, r, 2 * x + 2, m, rx); return max(s1, s2); } int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); int n; long long x; cin >> n >> x; vector<int> t(n); for (int i = 0; i < n; ++i) { cin >> t[i]; } // 1. 座標離散化 vector<long long> discrete_vals; for (int val : t) { discrete_vals.push_back(val); discrete_vals.push_back((long long)val + x); } sort(discrete_vals.begin(), discrete_vals.end()); discrete_vals.erase(unique(discrete_vals.begin(), discrete_vals.end()), discrete_vals.end()); map<long long, int> val_to_idx; for (int i = 0; i < discrete_vals.size(); ++i) { val_to_idx[discrete_vals[i]] = i; } // 2. 預處理 pre_lis 和 suf_lis vector<int> pre_lis = get_lis_lengths(t); vector<int> t_rev(n); for (int i = 0; i < n; ++i) { t_rev[i] = -t[n - 1 - i]; } vector<int> suf_lis_rev = get_lis_lengths(t_rev); vector<int> suf_lis(n); for (int i = 0; i < n; ++i) { suf_lis[i] = suf_lis_rev[n - 1 - i]; } // 3. 初始化答案 int max_len = 0; for (int len : pre_lis) { max_len = max(max_len, len); } // 4. 初始化線段樹 seg_tree_size = discrete_vals.size(); seg_tree.assign(4 * seg_tree_size, 0); // 5. 主迴圈,尋找最佳拼接 for (int j = 0; j < n; ++j) { // 查詢滿足 t_i < t_j + x 的所有 i < j 中,pre_lis[i] 的最大值 long long target_val = (long long)t[j] + x; auto it = lower_bound(discrete_vals.begin(), discrete_vals.end(), target_val); int query_range_end = it - discrete_vals.begin(); int max_pre = 0; if (query_range_end > 0) { max_pre = query_seg_tree(0, query_range_end, 0, 0, seg_tree_size); } if (max_pre > 0) { max_len = max(max_len, max_pre + suf_lis[j]); } // 將 pre_lis[j] 更新到線段樹中 int update_idx = val_to_idx[t[j]]; update_seg_tree(update_idx, pre_lis[j], 0, 0, seg_tree_size); } cout << max_len << endl; return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...