linux裝置驅動編寫入門
阿新 • • 發佈:2021-07-08
可惡,竟然連題目都無法正確拼出
可以用四個變數來表示左上左下右上右下的最大數(附加以絕對值化簡
由於如果非法會數值偏小直接忽略所以不用管,把每一段\(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();}