제출 #423156

#제출 시각아이디문제언어결과실행 시간메모리
423156abdzagFinancial Report (JOI21_financial)C++17
100 / 100
1101 ms53700 KiB
#include <bits/stdc++.h> using namespace std; #define FAST_IO ios_base::sync_with_stdio(0); cin.tie(nullptr) #define FOR(i, a, b) for (int i = (a); i <= (b); i++) #define REP(n) FOR(O, 1, (n)) #define f first #define s second #define pb push_back typedef pair<int, int> pii; typedef long long ll; typedef long double ld; typedef vector<int> vi; typedef vector<pii> vii; typedef vector<ll> vl; const int MAXN = 300100, MAXK = 20; const ll INF = 1e17; // DSU int par[MAXN], mn[MAXN]; int find(int a) { return par[a] = par[a] == a ? a : find(par[a]); } bool same(int a, int b) { return find(a) == find(b); } void unite(int a, int b) { a = find(a), b = find(b); if (a == b) return; par[b] = a; mn[a] = min(mn[a], mn[b]); } int n, d; int a[MAXN]; set<int> tmp; unordered_map<int, int> toId; // two segtrees. i am actually using only one in this solution (the second one was left from the solution for subtasks) int tree[2][4 * MAXN]; void upd(int tid, int p, int val, int id = 1, int le = 1, int ri = n) { if (le == ri) { tree[tid][id] = val; return; } int mid = (le + ri) / 2; if (p <= mid) upd(tid, p, val, 2 * id, le, mid); else upd(tid, p, val, 2 * id + 1, mid + 1, ri); tree[tid][id] = max(tree[tid][2 * id], tree[tid][2 * id + 1]); } int get(int tid, int x, int y, int id = 1, int le = 1, int ri = n) { if (x > ri || y < le) return 0; if (x <= le && ri <= y) return tree[tid][id]; int mid = (le + ri) / 2; return max(get(tid, x, y, 2 * id, le, mid), get(tid, x, y, 2 * id + 1, mid + 1, ri)); } bool cmp(int f, int s) { if (a[f] != a[s]) return a[f] < a[s]; return f > s; } vi seq; set<int> spec; int main() { FAST_IO; cin >> n >> d; FOR(i, 1, n) cin >> a[i]; FOR(i, 1, n) par[i] = i, mn[i] = i; // coordinate compression which ended up being not necessary in the full solution FOR(i, 1, n) tmp.insert(a[i]); int cur = 0; for (int x : tmp) toId[x] = ++cur; FOR(i, 1, n) a[i] = toId[a[i]]; FOR(i, 1, n) upd(0, i, a[i]); FOR(i, 1, n) seq.pb(i); // sorting by a[i] sort(seq.begin(), seq.end(), cmp); for (int i : seq) { auto it = spec.lower_bound(i); if (it != spec.end()) { int id = *it; if (abs(id - i) <= d) { unite(id, i); } } if (it != spec.begin()) { it--; int id = *it; if (abs(id - i) <= d) { unite(id, i); } } spec.insert(i); int cur = 1; // cur is the value of dp[i] int fr = mn[find(i)]; if (fr <= i - 1) cur = max(cur, get(1, fr, i - 1) + 1); upd(1, i, cur); } cout << (get(1, 1, n)) << "\n"; 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...