제출 #1311552

#제출 시각아이디문제언어결과실행 시간메모리
1311552Zbyszek99Seesaw (JOI22_seesaw)C++20
100 / 100
201 ms32908 KiB
#include <bits/stdc++.h> #include <ext/pb_ds/assoc_container.hpp> #include <ext/pb_ds/tree_policy.hpp> #define ll long long #define ld long double #define ull unsigned long long #define ff first #define ss second #define pii pair<int,int> #define pll pair<long long, long long> #define vi vector<int> #define vl vector<long long> #define pb push_back #define rep(i, b) for(int i = 0; i < (b); ++i) #define rep2(i,a,b) for(int i = a; i <= (b); ++i) #define rep3(i,a,b,c) for(int i = a; i <= (b); i+=c) #define count_bits(x) __builtin_popcountll((x)) #define all(x) (x).begin(),(x).end() #define siz(x) (int)(x).size() #define forall(it,x) for(auto& it:(x)) using namespace __gnu_pbds; using namespace std; typedef tree<int, null_type, less<int>, rb_tree_tag,tree_order_statistics_node_update> ordered_set; //mt19937 mt;void random_start(){mt.seed(chrono::time_point_cast<chrono::milliseconds>(chrono::high_resolution_clock::now()).time_since_epoch().count());} //ll rand(ll a, ll b) {return a + (mt() % (b-a+1));} const int INF = 1e9+50; const ll INF_L = 1e18+40; const ll MOD = 1e9+7; struct matrix { bool mat[2][2]; matrix() { rep(i,2) rep(j,2) mat[i][j] = 0; } matrix operator+(const matrix& d) { matrix res; if(mat[0][0] && d.mat[0][0]) res.mat[0][0] = 1; if(mat[0][1] && d.mat[1][0]) res.mat[0][0] = 1; if(mat[0][0] && d.mat[0][1]) res.mat[0][1] = 1; if(mat[0][1] && d.mat[1][1]) res.mat[0][1] = 1; if(mat[1][0] && d.mat[0][0]) res.mat[1][0] = 1; if(mat[1][1] && d.mat[1][0]) res.mat[1][0] = 1; if(mat[1][0] && d.mat[0][1]) res.mat[1][1] = 1; if(mat[1][1] && d.mat[1][1]) res.mat[1][1] = 1; return res; } }; const int tree_siz = 1024*512-1; matrix drzewo[tree_siz]; bool is_way() { rep(i,2) { rep(j,2) { if(drzewo[0].mat[i][j]) return true; } } return false; } void upd(int v) { drzewo[v-1] = drzewo[v*2-1] + drzewo[v*2]; if(v != 1) upd(v/2); } pii edges[200'001][2]; bool used[200'001][2]; ld val[200'001][2]; matrix mat[200'001]; void upd_poz(int ind) { rep(d1,2) rep(d2,2) mat[ind].mat[d1][d2] = 0; if(used[ind][0] && edges[ind][0].ff) mat[ind].mat[0][0] = 1; if(used[ind][0] && edges[ind][0].ss) mat[ind].mat[0][1] = 1; if(used[ind][1] && edges[ind][1].ff) mat[ind].mat[1][0] = 1; if(used[ind][1] && edges[ind][1].ss) mat[ind].mat[1][1] = 1; drzewo[tree_siz/2+ind] = mat[ind]; upd((tree_siz/2+ind+1)/2); } int main() { ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0); //random_start(); rep(i,tree_siz) { rep(d1,2) rep(d2,2) drzewo[i].mat[d1][d2] = 1; } int n; cin >> n; vector<ld> v(n+1); ld sum = 0; rep(i,n) { cin >> v[i+1]; sum += v[i+1]; } ld start_mid = sum / (ld)n; ld pop1 = sum; pii seg1 = {1,n}; ld pop2 = -1; pii seg2 = {-1,-1}; val[0][0] = sum/(ld)n; val[0][1] = -1e9; rep2(i,1,n-1) { if(pop2 == -1) { val[i][0] = (sum-v[n]) / (ld)(n-1); val[i][1] = (sum-v[1]) / (ld)(n-1); edges[i-1][0] = {1,1}; edges[i-1][1] = {0,0}; pop1 = sum-v[n]; pop2 = sum-v[1]; seg1 = {1,n-1}; seg2 = {2,n}; edges[i][0] = {1,1}; edges[i][1] = {1,1}; // cout << pop1 << " " << pop2 << "\n" << seg1.ff << " " << seg1.ss << "\n" << seg2.ff << " " << seg2.ss << " seg\n\n"; continue; } pair<ld,pii> next_L = {-1e16+1,{-1,-1}}; pair<ld,pii> next_R = {+1e16-1,{-1,-1}}; //L if((pop1 - v[seg1.ss]) / (ld)(n-i) <= start_mid) { next_L = max(next_L, {(pop1 - v[seg1.ss]),{seg1.ff,seg1.ss-1}}); } if((pop2 - v[seg2.ss]) / (ld)(n-i) <= start_mid) { next_L = max(next_L, {(pop2 - v[seg2.ss]),{seg2.ff,seg2.ss-1}}); } //R if((pop1 - v[seg1.ff]) / (ld)(n-i) >= start_mid) { next_R = min(next_R, {(pop1 - v[seg1.ff]),{seg1.ff+1,seg1.ss}}); } if((pop2 - v[seg2.ff]) / (ld)(n-i) >= start_mid) { next_R = min(next_R, {(pop2 - v[seg2.ff]),{seg2.ff+1,seg2.ss}}); } edges[i-1][0] = {0,0}; edges[i-1][1] = {0,0}; // 0 0 if(seg1.ff == next_L.ss.ff && seg1.ss-1 == next_L.ss.ss) { edges[i-1][0].ff = 1; } if(seg1.ff+1 == next_L.ss.ff && seg1.ss == next_L.ss.ss) { edges[i-1][0].ff = 1; } // 0 1 if(seg1.ff + 1 == next_R.ss.ff && seg1.ss == next_R.ss.ss) { edges[i-1][0].ss = 1; } if(seg1.ff == next_R.ss.ff && seg1.ss -1 == next_R.ss.ss) { edges[i-1][0].ss = 1; } // 1 0 if(seg2.ff == next_L.ss.ff && seg2.ss-1 == next_L.ss.ss) { edges[i-1][1].ff = 1; } if(seg2.ff+1 == next_L.ss.ff && seg2.ss == next_L.ss.ss) { edges[i-1][1].ff = 1; } // 1 1 if(seg2.ff + 1 == next_R.ss.ff && seg2.ss == next_R.ss.ss) { edges[i-1][1].ss = 1; } if(seg2.ff == next_R.ss.ff && seg2.ss -1 == next_R.ss.ss) { edges[i-1][1].ss = 1; } val[i][0] = next_L.ff / (ld)(n-i); val[i][1] = next_R.ff / (ld)(n-i); pop1 = next_L.ff; pop2 = next_R.ff; seg1 = next_L.ss; seg2 = next_R.ss; edges[i][0] = {1,1}; edges[i][1] = {1,1}; // cout << pop1 << " " << pop2 << "\n" << seg1.ff << " " << seg1.ss << "\n" << seg2.ff << " " << seg2.ss << " seg\n\n"; } vector<pair<ld,pii>> points; rep(i,n) { points.pb({val[i][0],{i,0}}); if(i != 0) { points.pb({val[i][1],{i,1}}); } upd_poz(i); } sort(all(points)); ld ans = 1e16; int p = 0; int k = 0; while(p < siz(points)) { if(p != 0) { used[points[p-1].ss.ff][points[p-1].ss.ss] = 0; upd_poz(points[p-1].ss.ff); } used[points[p].ss.ff][points[p].ss.ss] = 1; upd_poz(points[p].ss.ff); while(!is_way() && k+1 < siz(points)) { k++; used[points[k].ss.ff][points[k].ss.ss] = 1; upd_poz(points[k].ss.ff); } // cout << p << " " << k << " " << is_way() << " two\n"; if(is_way()) { ans = min(ans,points[k].ff-points[p].ff); } else break; p++; } cout << setprecision(10) << ans << "\n"; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...