CF263E Rhombus

发现(f(x,y))即是每个点到此点的距离乘上权值。

考虑挪一下会有什么影响。

往下挪:
0 0 0 1 0 0 0      0 0 0 0 0 0 0      0 0 0 - 0 0 0
0 0 1 2 1 0 0      0 0 0 1 0 0 0      0 0 - - - 0 0
0 1 2 3 2 1 0  -- 0 0 1 2 1 0 0  -- 0 - - - - - 0
0 0 1 2 1 0 0  --/ 0 1 2 3 2 1 0  --/ 0 + + + + + 0
0 0 0 1 0 0 0      0 0 1 2 1 0 0      0 0 + + + 0 0
0 0 0 0 0 0 0      0 0 0 1 0 0 0      0 0 0 + 0 0 0
往右挪:
0 0 0 1 0 0 0      0 0 0 0 1 0 0      0 0 0 - + 0 0
0 0 1 2 1 0 0      0 0 0 1 2 1 0      0 0 - - + + 0
0 1 2 3 2 1 0  -- 0 0 1 2 3 2 1  -- 0 - - - + + +
0 0 1 2 1 0 0  --/ 0 0 0 1 2 1 0  --/ 0 0 - - + + 0
0 0 0 1 0 0 0      0 0 0 0 1 0 0      0 0 0 - + 0 0
0 0 0 0 0 0 0      0 0 0 0 0 0 0      0 0 0 0 0 0 0

发现变化的是一片三角形区域,考虑(duliu)前后缀处理即可。

代码细节较多,参考价值不大:

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=2e3+5;
const int mod=1e9+7;
int n,m,a[N][N],k;
inline int read(){
	int x=0,f=1;char c=getchar();
	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
	while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
	return x*f;
}
int s[N],l[N][N],r[N][N],z[N][N],y[N][N];
int sum[N][N],f[N][N],g[N][N];
signed main(){
	n=read(),m=read(),k=read();
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			a[i][j]=read();
	for(int j=1;j<=m;j++)
		for(int i=1;i<=n;i++){
			s[i]=s[i-1]+a[i][j];
			l[i][j]=l[i-1][j-1]+s[i];
		}
	for(int j=m;j>=1;j--)
		for(int i=1;i<=n;i++){
			s[i]=s[i-1]+a[i][j];
			r[i][j]=r[i-1][j+1]+s[i];
		}
	/*
	puts("l array is as follow");
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++)
			printf("%d ",l[i][j]);
		puts("");
	}puts("r array is as follow");
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++)
			printf("%d ",r[i][j]);
		puts("");
	}puts("");
	*/
	memset(s,0,sizeof(s));
	for(int i=1;i<=n;i++)
		for(int j=m;j>=1;j--){
			s[j]=s[j+1]+a[i][j];
			y[i][j]=y[i-1][j+1]+s[j];
		}
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++){
			s[j]=s[j-1]+a[i][j];
			z[i][j]=z[i-1][j-1]+s[j];
		}
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			f[i][j]=f[i-1][j]+f[i][j-1]-f[i-1][j-1]+a[i][j];
	for(int i=1;i<=n;i++)
		for(int j=m;j>=1;j--)
			g[i][j]=g[i-1][j]+g[i][j+1]-g[i-1][j+1]+a[i][j];
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			sum[k][k]+=a[i][j]*max(0ll,k-abs(k-i)-abs(k-j));
	for(int i=k+1;i<=n-k+1;i++){
		sum[i][k]=sum[i-1][k]+r[i+k-1][k]-r[i-1][k+k];
		sum[i][k]=sum[i][k]-f[i-1][k+k-1]+f[i-1][k-1];
		sum[i][k]=sum[i][k]+l[i+k-2][k-1]-f[i-1][k-1];
		sum[i][k]=sum[i][k]-z[i-1][k+k-1]+z[i-k-1][k-1];
		sum[i][k]=sum[i][k]+f[i-1][k-1]-f[i-k-1][k-1];
		sum[i][k]=sum[i][k]-y[i-1][1]+y[i-k][k];
		sum[i][k]=sum[i][k]+g[i-1][k]-g[i-k][k];
	}
	for(int i=k;i<=n-k+1;i++)
		for(int j=k+1;j<=m-k+1;j++){
			sum[i][j]=sum[i][j-1]+r[i+k-1][j]-r[i-1][j+k];
			sum[i][j]=sum[i][j]-l[i-1][j+k-1];
			sum[i][j]=sum[i][j]-l[i+k-1][j-1]+l[i-1][j-k-1];
			sum[i][j]=sum[i][j]+r[i-1][j-k];
			if(i>k)sum[i][j]=sum[i][j]+l[i-k-1][j-1]-r[i-k-1][j];
			//printf("%d %d
",i,j);
			//printf("%d ",r[i+k-1][j]-r[i-1][j+k]-l[i-1][j+k-1]+l[i-k-1][j-1]);
			//printf("%d
",-l[i+k-1][j-1]+l[i-1][j-k-1]+r[i-1][j-k]-r[i-k-1][j]);
		}
	/*
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++)
			printf("%d ",sum[i][j]);
		puts("");
	}puts("");
	*/
	int ax,ay,ans=-1;
	for(int i=k;i<=n-k+1;i++)
		for(int j=k;j<=m-k+1;j++)
			if(ans<sum[i][j])ans=sum[i][j],ax=i,ay=j;
	printf("%lld %lld
",ax,ay);
	return 0;
}

深深地感到自己的弱小。

原文地址:https://www.cnblogs.com/syzf2222/p/14320393.html