Submission #94829

#TimeUsernameProblemLanguageResultExecution timeMemory
94829popovicirobertTeams (CEOI11_tea)C++14
70 / 100
2555 ms60860 KiB
#include <bits/stdc++.h> #define lsb(x) (x & (-x)) #define ll long long #define ull unsigned long long #define ld long double // 217 // 44 using namespace std; const int INF = 1e9; const int MAXN = (int) 1e6; struct SegTree { vector < pair <int, int> > aint; int n; inline void init(int _n) { n = _n; aint.resize(4 * n + 1); } inline void reset() { for(int i = 1; i <= 4 * n; i++) { aint[i] = {-INF, i}; } } inline void refresh(int nod) { if(aint[2 * nod].first < aint[2 * nod + 1].first) { aint[nod] = aint[2 * nod + 1]; } else { aint[nod] = aint[2 * nod]; } } void update(int nod, int left, int right, int pos, int val) { if(left == right) { aint[nod] = {val, left}; } else { int mid = (left + right) / 2; if(pos <= mid) update(2 * nod, left, mid, pos, val); else update(2 * nod + 1, mid + 1, right, pos, val); refresh(nod); } } pair <int, int> query(int nod, int left, int right, int l, int r) { if(l <= left && right <= r) { return aint[nod]; } else { int mid = (left + right) / 2; pair <int, int> a = {-INF, 0}, b = {-INF, 0}; if(l <= mid) a = query(2 * nod, left, mid, l, r); if(mid < r) b = query(2 * nod + 1, mid + 1, right, l, r); if(a.first < b.first) { return b; } return a; } } }st; pair <int, int> arr[MAXN + 1]; pair <int, int> best[MAXN + 1]; int dp[MAXN + 1], from[MAXN + 1]; inline int check(int n, int len) { st.reset(); st.update(1, 0, n, 0, 0); for(int i = 1; i <= n; i++) { if(i - arr[i].first < 0) { dp[i] = -INF; } else { pair <int, int> cur = st.query(1, 0, n, max(0, i - len), i - arr[i].first); dp[i] = cur.first + 1; from[i] = cur.second; st.update(1, 0, n, i, dp[i]); } } return dp[n]; } int main() { //ifstream cin("A.in"); //ofstream cout("A.out"); int i, n; ios::sync_with_stdio(false); cin.tie(0), cout.tie(0); cin >> n; for(i = 1; i <= n; i++) { cin >> arr[i].first; arr[i].second = i; } sort(arr + 1, arr + n + 1); for(i = 1; i <= n; i++) { if(i - arr[i].first < 0) { dp[i] = -INF; } else { dp[i] = best[i - arr[i].first].first + 1; from[i] = best[i - arr[i].first].second; } best[i] = best[i - 1]; if(best[i].first < dp[i]) { best[i] = {dp[i], i}; } } st.init(n); int ans = dp[n]; cout << ans << "\n"; int res = arr[n].first - 1; for(int step = 1 << 20; step; step >>= 1) { if(res + step <= n && check(n, res + step) < ans) { res += step; } } check(n, res + 1); int pos = n; while(pos > 0) { cout << pos - from[pos] << " "; for(i = from[pos] + 1; i <= pos; i++) { cout << arr[i].second << " "; } cout << "\n"; pos = from[pos]; } //cin.close(); //cout.close(); 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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...