Submission #512174

#TimeUsernameProblemLanguageResultExecution timeMemory
512174blueTeams (CEOI11_tea)C++17
100 / 100
2279 ms113192 KiB
#include <iostream> #include <vector> #include <algorithm> using namespace std; using vi = vector<int>; using pii = pair<int, int>; using vvi = vector<vi>; #define sz(x) int(x.size()) const int INF = 100'000'000; const int Z = (1<<20); vector<int> segtree; void set(int i, int v) { i += Z; segtree[i] = v; for(i >>= 1; i >= 1; i >>= 1) segtree[i] = max(segtree[i<<1], segtree[(i<<1) | 1]); } vector<pii> segtree2; void set2(int i, int v) { // cerr << "\n\n" << "set2 " << i << ' ' << v << '\n'; i += Z; segtree2[i].first = v; for(i >>= 1; i >= 1; i >>= 1) segtree2[i] = max(segtree2[i<<1], segtree2[(i<<1) | 1]); // cerr << "root = " << segtree2[1] } int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); int n; cin >> n; pii a[1+n]; for(int i = 1; i <= n; i++) { cin >> a[i].first; a[i].second = i; } sort(a+1, a+n+1); int t; vi dp(1+n); vi dpmx(1+n); dp[0] = dpmx[0] = 0; for(int i = 1; i <= n; i++) { t = -INF; if(a[i].first > i) { ; } else { if(i - a[i].first >= 0) t = dpmx[i - a[i].first]; } dp[i] = max(-INF, t + 1); dpmx[i] = max(dp[i], dpmx[i-1]); // cerr << i << " : " << t << '\n'; } int team_count = dp[n]; // int Z = (1<<20); int z = 0; for(int i = 1; i <= n; i++) z = max(z, a[i].first); int lo = 1, hi = n; while(lo != hi) { int mxs = (lo+hi)/2; segtree = vector<int>(Z<<1, -INF); int l = 0; int r = -1; vi new_dp(1+n, -INF); new_dp[0] = 0; // cerr << "n = " << n << '\n'; for(int i = 1; i <= n; i++) { int nl = max(0, i-mxs); int nr = max(-1, i - a[i].first); if(nl > nr) continue; if(nr - nl < 30) { for(int g = nl; g <= nr; g++) new_dp[i] = max(new_dp[i], new_dp[g]+1); continue; } while(r < nr) { r++; set(r, new_dp[r]); } while(l > nl) { l--; set(l, new_dp[l]); } while(r > nr) { set(r, -INF); r--; } while(l < nl) { set(l, -INF); l++; } new_dp[i] = max(-INF, segtree[1]+1); } if(new_dp[n] == team_count) hi = mxs; else lo = mxs+1; } // cerr << team_count << ' ' << lo << '\n'; int mxs = lo; // cerr << "\n\n\n\n\n"; // cerr << lo << ' ' << hi << " : " << mxs << '\n'; segtree2 = vector<pii>(Z<<1, {-INF, -1}); for(int i = 0; i <= n; i++) segtree2[Z+i].second = i; int l = 0; int r = -1; vi new_dp(1+n, -INF); new_dp[0] = 0; vi prv(1+n, -1); // cerr << "n = " << n << '\n'; for(int i = 1; i <= n; i++) { int nl = max(0, i-mxs); int nr = max(-1, i - a[i].first); if(nr - nl < 20) { for(int i2 = nl; i2 <= nr; i2++) { if(new_dp[i2]+1 >= new_dp[i]) { new_dp[i] = new_dp[i2] + 1; prv[i] = i2; } } continue; } // if(i-mxs > i - a[i]) con // cerr << "i = " << i << " : " << "nl nr = " << nl << ' ' << nr << '\n'; if(nl > nr) continue; // cerr << "journey " << l << ' ' << r << " -> " << nl << ' ' << nr << '\n'; while(r < nr) { r++; set2(r, new_dp[r]); } while(l > nl) { l--; set2(l, new_dp[l]); } while(r > nr) { set2(r, -INF); r--; } while(l < nl) { set2(l, -INF); l++; } // cerr << l << ' ' << r << '\n'; // cerr << "st = " << segtree2[1].first << ' ' << segtree2[1].second << '\n'; new_dp[i] = max(-INF, segtree2[1].first+1); prv[i] = segtree2[1].second; // cerr << i << " : " << new_dp[i] << ' ' << prv[i] << '\n'; } vvi teams; int I = n; while(I != 0) { teams.push_back(vi(0)); // cerr << I << ' ' << prv[I] << '\n'; for(int q = I; q > prv[I]; q--) teams.back().push_back(a[q].second); I = prv[I]; } cout << team_count << '\n'; for(int f = 0; f < team_count; f++) { cout << sz(teams[f]) << ' '; for(int w: teams[f]) cout << w << ' '; cout << '\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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...