#include using namespace std; using pii=pair; using tii=tuple; using qii=tuple; using ll=long long; using ld=long double; const int INF=1e9; #define rep(i,n) for (int i=0;i<(int)(n);i++) #define all(v) v.begin(),v.end() template void chmin(T &a,T b){ if(a>b){ a=b; } } template void chmax(T &a,T b){ if(a> tree; //0->back,1->front->2->center struct Solver{ double score(vector> &ans){ ll sum_h2=0; int sum_h=0; rep(i,K){ int now=0; rep(j,4){ now+=tree[min(2,j)][ans[i][j]].h; } sum_h2+=(ll)now*(ll)now; sum_h+=now; } return ((double)sum_h2/(double)K)-((double)sum_h/(double)K)*((double)sum_h/(double)K); } int true_score(vector> &ans){ int mx=-INF,mn=INF; rep(i,K){ int now=0; rep(j,4){ now+=tree[min(2,j)][ans[i][j]].h; } chmax(mx,now); chmin(mn,now); } return mx-mn; } void solve(){ set st_back,st_center; rep(i,N) st_back.insert({tree[0][i].w,i}); rep(i,2*N) st_center.insert({tree[2][i].w,i}); vector> ans(K,vector(4,-10)); //back->front->center1->center2 int cnt_tree=0; vector front_ord(N),center_ord(2*N); rep(i,N) front_ord[i]=i; rep(i,2*N) center_ord[i]=i; sort(all(front_ord),[&](int i,int j){return tree[1][i].w> used(3,vector(2*N,0)); rep(i,K){ rep(j,4){ used[min(2,j)][ans[i][j]]=1; } } vector> not_used(3); rep(i,3){ rep(j,2*N){ if(i!=2&&j==N) break; if(!used[i][j]) not_used[i].push_back(j); } } mt19937 mt; set st; vector sum_h(K,0); rep(i,K){ rep(j,4){ sum_h[i]+=tree[min(2,j)][ans[i][j]].h; } st.insert({sum_h[i],i}); } int min_score=(*st.rbegin()).first-(*st.begin()).first; int limit_time=1200; auto start=chrono::system_clock::now(); while(true){ auto now=chrono::system_clock::now(); int ms=chrono::duration_cast(now-start).count(); if(limit_time<=ms) break; int x=(*st.rbegin()).second,y=mt()%4; if(mt()%2==0) x=(*st.begin()).second; int r=mt()%10; if(r<=2){ int p=mt()%K,q=y; if(x==p) continue; if(2<=y) q=2+mt()%2; st.erase({sum_h[x],x}); st.erase({sum_h[p],p}); int before_sum_h_x=sum_h[x],before_sum_h_p=sum_h[p]; sum_h[x]-=tree[min(2,y)][ans[x][y]].h; sum_h[p]-=tree[min(2,y)][ans[p][q]].h; sum_h[x]+=tree[min(2,y)][ans[p][q]].h; sum_h[p]+=tree[min(2,y)][ans[x][y]].h; swap(ans[x][y],ans[p][q]); st.insert({sum_h[x],x}); st.insert({sum_h[p],p}); bool ok=true; rep(i,3){ if(tree[min(2,i+1)][ans[x][i+1]].w<=tree[min(2,i)][ans[x][i]].w){ ok=false; break; } } rep(i,3){ if(tree[min(2,i+1)][ans[p][i+1]].w<=tree[min(2,i)][ans[p][i]].w){ ok=false; break; } } int new_score=(*st.rbegin()).first-(*st.begin()).first; double temp=8.0+(0.5-8.0)*(double)ms/(double)limit_time; double prob=exp((double)(min_score-new_score)/temp); if(ok&&1.0*(double)mt()/(double)mt19937::max() v; rep(i,4){ if(i==y) continue; v.push_back(i); } int z=v[mt()%(int)v.size()]; int p=mt()%(int)not_used[min(2,y)].size(),q=mt()%(int)not_used[min(2,z)].size(); if(min(2,y)==min(2,z)&&p==q) continue; int before_sum_h_x=sum_h[x]; st.erase({sum_h[x],x}); sum_h[x]-=tree[min(2,y)][ans[x][y]].h; sum_h[x]-=tree[min(2,z)][ans[x][z]].h; sum_h[x]+=tree[min(2,y)][not_used[min(2,y)][p]].h; sum_h[x]+=tree[min(2,z)][not_used[min(2,z)][q]].h; swap(ans[x][y],not_used[min(2,y)][p]); swap(ans[x][z],not_used[min(2,z)][q]); st.insert({sum_h[x],x}); bool ok=true; rep(i,3){ if(tree[min(2,i+1)][ans[x][i+1]].w<=tree[min(2,i)][ans[x][i]].w){ ok=false; break; } } int new_score=(*st.rbegin()).first-(*st.begin()).first; double temp=8.0+(0.5-8.0)*(double)ms/(double)limit_time; double prob=exp((double)(min_score-new_score)/temp); if(ok&&1.0*(double)mt()/(double)mt19937::max()> N >> K; tree.resize(3); tree[1].resize(N); tree[2].resize(2*N); tree[0].resize(N); rep(i,N) cin >> tree[1][i].w; rep(i,N) cin >> tree[1][i].h; rep(i,2*N) cin >> tree[2][i].w; rep(i,2*N) cin >> tree[2][i].h; rep(i,N) cin >> tree[0][i].w; rep(i,N) cin >> tree[0][i].h; Solver.solve(); }