#define re register #include using namespace std; const int nmax=5e2+42; double T=clock(),output_coeff=1/1e5; double TL; int n,m,q; int row[nmax],col[nmax]; int inp[nmax][nmax],b[nmax][nmax]; inline char nc() { static char buf[100000],*p1,*p2; return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++; } int rd() { int x=0; char ch=nc(); while(ch<'0'||ch>'9') ch=nc(); while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=nc(); return x; } /* void read(int &ret) { ret=0; char c=getchar(); while(isdigit(c)==0)c=getchar(); while(isdigit(c)) { ret=ret*10+c-'0'; c=getchar(); } } */ long long score=0; struct line { char type; int which,k; long long diff,total_diff; }; vector outp; line make_line(char type,int which,int k,long long diff,long long total_diff) { line ret; ret.type=type; ret.which=which; ret.k=k; ret.diff=diff; ret.total_diff=total_diff; return ret; } int help[nmax]; long long now_row[nmax][nmax]/*which, k*/,now_col[nmax][nmax]/*k, which*/; long long old_row[nmax],old_col[nmax]; void recalc_old() { memset(old_row,0,sizeof(old_row)); memset(old_col,0,sizeof(old_col)); //row for(int which=1;which<=n;which++) { for(int j=1;j<=m;j++) old_row[which]+=inp[which][j]*b[which][j]; } //column for(int i=1;i<=n;i++) for(int which=1;which<=m;which++) { old_col[which]+=inp[i][which]*b[i][which]; } } void push(char type,int which,int k) { if(type=='R') { //column subtract for(int k_now=1;k_now> 1); i++) root[i] = complex_base(cos(ang * i), sin(ang * i)); last_n_fft = n; } for(int i = 1; i < n; i++) { bit_rev[i] = (bit_rev[i >> 1] >> 1) | ((i & 1) << (lg - 1)); if(bit_rev[i] < i) swap(a[i], a[bit_rev[i]]); } for(int len = 2; len <= n; len <<= 1) { int step = (n / len); for(int j = 0; j < (len >> 1); j++) for(int i = 0; i < n; i += len) { complex_base u = a[i + j], v = root[step * j] * a[i + j + (len >> 1)]; a[i + j] = u + v; a[i + j + (len >> 1)] = u - v; } } } void inv_fft(complex_base *a, int lg) { int n = (1 << lg); if(ilast_n_fft != n) { double ang = -2 * PI / n; for(int i = 0; i < (n >> 1); i++) iroot[i] = complex_base(cos(ang * i), sin(ang * i)); ilast_n_fft = n; } for(int i = 1; i < n; i++) { bit_rev[i] = (bit_rev[i >> 1] >> 1) | ((i & 1) << (lg - 1)); if(bit_rev[i] < i) swap(a[i], a[bit_rev[i]]); } for(int len = 2; len <= n; len <<= 1) { int step = (n / len); for(int j = 0; j < (len >> 1); j++) for(int i = 0; i < n; i += len) { complex_base u = a[i + j], v = iroot[step * j] * a[i + j + (len >> 1)]; a[i + j] = u + v; a[i + j + (len >> 1)] = u - v; } } for(int i = 0; i < n; i++) a[i] /= n; } complex_base A[MAXN], B[MAXN]; vector mult(vector a, vector b) { if(a.size() * b.size() <= 256) { vector ans(a.size() + b.size(), 0); for(int i = 0; i < (int)a.size(); i++) for(int j = 0; j < (int)b.size(); j++) ans[i + j] += a[i] * b[j]; return ans; } int lg = 0; while((1 << lg) < (int)(a.size() + b.size())) ++lg; for(int i = 0; i < (1 << lg); i++) A[i] = B[i] = complex_base(0, 0); for(int i = 0; i < (int)a.size(); i++) A[i] = complex_base(a[i], 0); for(int i = 0; i < (int)b.size(); i++) B[i] = complex_base(b[i], 0); fft(A, lg); fft(B, lg); for(int i = 0; i < (1 << lg); i++) A[i] = A[i] * B[i]; inv_fft(A, lg); vector ans(a.size() + b.size(), 0); for(int i = 0; i < (int)ans.size(); i++) ans[i] = (long long)(A[i].x + 0.5); return ans; } //-------------------- line get_line_1() { char type; int best_which,best_k; long long best_diff=-1e18; //test row for(int which=1;which<=n;which++) { for(int j=1;j > get_best_start_row() { vector< pair > > best_start={}; for(int which_first=1;which_first<=n;which_first++) //for(int k_first=1;k_firstnow_row[which_first][i])k_first=i; best_start.push_back({-(old_row[which_first]-now_row[which_first][k_first]),{which_first,k_first}}); } sort(best_start.begin(),best_start.end()); //for(auto w:best_start)cout< > ret={}; for(int i=0;i > get_best_start_col() { vector< pair > > best_start={}; for(int which_first=1;which_first<=m;which_first++) //for(int k_first=1;k_firstnow_col[j][which_first])k_first=j; //long long diff_first=old_col[which_first]-now_col[k_first][which_first]; best_start.push_back({-(old_col[which_first]-now_col[k_first][which_first]),{k_first,which_first}}); } sort(best_start.begin(),best_start.end()); vector< pair > ret={}; for(int i=0;i=2) { line cur=get_line_1(); if(best_diff=2) { line cur=get_line_1(); if(best_diff=2) { line cur=get_line_1(); if(best_diff=2) { line cur=get_line_1(); if(best_diff=1) { line cur=get_line_2(); if(best_diff=1) { line cur=get_line_2(); if(best_diff best={score,0}; TL=4.6; while(q&&1.0*(clock()-T)/CLOCKS_PER_SEC+outp.size()*output_coeffscore) { best={score,outp.size()}; } //cout<best.second)outp.pop_back(); score=best.first; //cout<<"score= "< best={score,0}; TL=4.75; while(q&&1.0*(clock()-T)/CLOCKS_PER_SEC+outp.size()*output_coeffscore) { best={score,outp.size()}; } //cout<best.second)outp.pop_back(); score=best.first; //cout<<"score= "< best={score,0}; TL=4.825; TAKE=15*2*100*100/(n*n+m*m); //cout<<"TAKE= "<score) { best={score,outp.size()}; } //cout<best.second)outp.pop_back(); score=best.first; //cout<<"score= "< LHS(m+1,0); for(int j=1;j<=m;j++)LHS[j]=inp[which][j]; vector RHS(m+1,0); for(int j=1;j<=m;j++)RHS[m-j]=b[which][j]; vector help=mult(LHS,RHS); for(int i=1;i<=m;i++)now_row[which][i]=row[which]; for(int i=1;i LHS(n+1,0); for(int i=1;i<=n;i++)LHS[i]=inp[i][which]; vector RHS(n+1,0); for(int i=1;i<=n;i++)RHS[n-i]=b[i][which]; vector help=mult(LHS,RHS); for(int j=1;j<=n;j++)now_col[j][which]=col[which]; for(int i=1;i best={score,0}; TL=4.85; while(q&&1.0*(clock()-T)/CLOCKS_PER_SEC+outp.size()*output_coeffscore) { best={score,outp.size()}; } //cout<best.second)outp.pop_back(); score=best.first; //cout<<"score= "<