#include using namespace std; typedef signed long long ll; #define _P(...) (void)printf(__VA_ARGS__) #define FOR(x,to) for(x=0;x<(to);x++) #define FORR(x,arr) for(auto& x:arr) #define FORR2(x,y,arr) for(auto& [x,y]:arr) #define ALL(a) (a.begin()),(a.end()) #define ZERO(a) memset(a,0,sizeof(a)) #define MINUS(a) memset(a,0xff,sizeof(a)) template bool chmax(T &a, const T &b) { if(a bool chmin(T &a, const T &b) { if(a>b){a=b;return 1;}return 0;} //------------------------------------------------------- int H,W; ll A[3030][3030]; template pair> Hungarian(vector>& A) { const int MV=1010; int match[MV+1], vis[MV+1]; int N=A.size(); assert(A[0].size()==N && MV>=2*N); int y,x,i,j; vector R(N),C(N,0); FOR(y,N) R[y]=*max_element(ALL(A[y])); MINUS(match); while(1) { retry: FOR(y,N) if(match[y]==-1) break; if(y==N) break; int tar=y; MINUS(vis); queue Q; vector S,T; Q.push(tar); FOR(y,N) T.push_back(y); ret2: while(Q.size()) { y=Q.front(); Q.pop(); if(vis[y]==-1) S.push_back(y); vis[y]=0; vector T2; FORR(x,T) { if(A[y][x]==R[y]+C[x]) { vis[N+x]=y; if(match[N+x]==-1) { //交代路を張る int cur=N+x; while(1) { int nex=match[y]; match[cur]=y; match[y]=cur; if(y==tar) goto retry; cur=nex; y=vis[cur]; } } Q.push(match[N+x]); } else T2.push_back(x); } swap(T,T2); } //交代路が無い V dif=numeric_limits::max(); int ty=-1,tx=-1; FORR(y,S) FORR(x,T) if(R[y]+C[x]-A[y][x]=0) R[i]-=dif; FOR(i,N) if(vis[i+N]>=0) C[i]+=dif; Q.push(ty); goto ret2; } vector P; ll ret=0; FOR(y,N) P.push_back(match[y]-N), ret+=A[y][match[y]-N]; return {ret,P}; } void solve() { int i,j,k,l,r,x,y; string s; cin>>H>>W; FOR(y,H) FOR(x,W) cin>>A[y][x]; vector> B; B.resize(H/2); FORR(b,B) b.resize(H/2); FOR(i,H/2) FOR(j,H/2) { FOR(x,W) B[i][j]=max(B[i][j],A[H-1-j][x]-A[i][x]); } cout<