题解 biology
可恶,竟然连题目都无法正确拼出
可以用四个变量来表示左上左下右上右下的最大数(附加以绝对值化简
由于如果非法会数值偏小直接忽略所以不用管,把每一段\(a\)数组相等的先查找再修改即可。
Code
#include<cstring>
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
namespace EMT{
#define pf printf
#define F(i,a,b) for(register int i=a;i<=b;i++)
#define D(i,a,b) for(register int i=a;i>=b;i--)
typedef long long ll;
inline int read(){int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();return x*f;}
inline ll min(ll a,ll b){return a<b?a:b;}inline ll max(ll a,ll b){return a>b?a:b;}
inline void pi(ll x){pf("%lld ",x);}inline void pn(){pf("\n");}
inline void file(){freopen("in.in","r",stdin);freopen("my.out","w",stdout);}
inline ll abs(ll x){return x<0?-x:x;}
const int N=2e3+100;
int n,m,cnt;ll ans;
struct node{int a,b,x,y;}t[N*N];
int minn=0x7fffffff;
inline bool cmp(node a,node b){return a.a<b.a;}
ll tt[5];
struct wen{ll a,b,c,d;}q;
inline void add(int k,ll v){
int x=t[k].x,y=t[k].y;
tt[1]=max(tt[1],v-x-y);
tt[2]=max(tt[2],v-x+y);
tt[3]=max(tt[3],v-y+x);
tt[4]=max(tt[4],v+x+y);
}
inline void get(int k){
int x=t[k].x,y=t[k].y;
q.a=tt[1]+x+y;
q.b=tt[2]+x-y;
q.c=tt[3]+y-x;
q.d=tt[4]-x-y;
}
ll rec[N*N];
inline short main(){
//file();
F(i,1,4)tt[i]=-minn;
n=read();m=read();
F(i,1,n)F(j,1,m){t[++cnt].a=read();t[cnt].x=i;t[cnt].y=j;if(t[cnt].a)minn=min(t[cnt].a,minn);}cnt=0;
F(i,1,n)F(j,1,m)t[++cnt].b=read();
std::sort(t+1,t+cnt+1,cmp);
int l=1,r=cnt,Ans=cnt+1;
while(l<=r){
int mid=(l+r)>>1;
if(!t[mid].a)l=mid+1;
else r=mid-1,Ans=mid;
}
int key=cnt+1;
F(i,Ans,cnt)if(t[i].a==minn)add(i,t[i].b),ans=max(ans,t[i].b);else {key=i;break;}
while(key<=cnt){
int r=cnt+1;
F(i,key,cnt)
if(i==key||t[i].a==t[i-1].a)get(i),rec[i]=max(q.a,max(q.b,max(q.c,q.d)))+t[i].b;
else {r=i;break;}
F(i,key,r-1)add(i,rec[i]);key=r;
}
F(i,Ans,n*m)ans=max(ans,rec[i]);
pi(ans);
return 0;
}
}
signed main(){return EMT::main();}
Everything that kills me makes me feel alive.