CF263E

小丑,做这种题做半天。

首先发现有贡献的位置是一个斜正方形,从内到外贡献系数依次递减。先拆成四个部分(四个直角三角形),每次将整个矩形旋转来分别做,最后简单容斥一下。

考虑对于一个直角三角形怎么计算贡献。考虑从它左边的一个三角形转移过来。设定点为 (i,j) 的三角形贡献为 fi,j,里面数之和为 gi,j,则 fi,j=fi,j1gi,j1 再加上三角形最右边一列的贡献。很多都可以预处理出来前缀和解决。

gi,j 也可以转移,方法应该很多,我的方法是从 gi1,j+1 转来再减去一列加上一行。只用单独处理 j=m 的情况。

细节挺多。因为做法比较烂/kk。

code:

点击查看代码
int n,m,k,a[N][N],b[N][N];ll c[N][N][2],d[N][N][2],f[N][N],g[N][N],ans[N][N];
il ll getx(int i,int j){return (c[i][j][1]-c[max(i-k,0)][j][1])-(i-k)*(c[i][j][0]-c[max(i-k,0)][j][0]);}
void solve(int op){
	mems(f,0),mems(g,0),mems(c,0),mems(d,0);
	rep(i,1,n){
		rep(j,1,m){
			c[i][j][0]=c[i-1][j][0]+a[i][j];
			c[i][j][1]=c[i-1][j][1]+1ll*a[i][j]*i;
			d[i][j][0]=d[i][j-1][0]+a[i][j];
			d[i][j][1]=d[i][j-1][1]+1ll*a[i][j]*j;
		}
	}
	rep(i,1,n){
		f[i][1]=getx(i,1),g[i][1]=c[i][1][0]-c[max(i-k,0)][1][0];
		rep(j,2,m){
			f[i][j]=f[i][j-1]-g[i][j-1]+getx(i,j);
			g[i][j]=g[i-1][j+1]-(c[i-1][j+1][0]-c[max(i-1-k,0)][j+1][0])+(d[i][j][0]-d[i][max(j-k,0)][0]);
		}
		g[i][m]=g[i][m-1];
		int x=i,y=m-k;
		while(x&&y<m)g[i][m]-=a[x--][y++];
		g[i][m]+=c[i][m][0]-c[max(i-k,0)][m][0];
		rep(j,1,m){
			f[i][j]-=getx(i,j);
			if(op==1)ans[i][j]+=f[i][j];
			if(op==2)ans[j][n-i+1]+=f[i][j];
			if(op==3)ans[n-i+1][m-j+1]+=f[i][j];
			if(op==4)ans[m-j+1][i]+=f[i][j];
		}
	}
}
void turn(){
	rep(i,1,n)rep(j,1,m)b[m-j+1][i]=a[i][j];
	swap(n,m);
	rep(i,1,n)rep(j,1,m)a[i][j]=b[i][j];
}
void Yorushika(){
	scanf("%d%d%d",&n,&m,&k);
	rep(i,1,n)rep(j,1,m)scanf("%d",&a[i][j]);
	rep(i,1,4)solve(i),turn();
	int x=k,y=k;
	rep(i,k,n-k+1)rep(j,k,m-k+1)if((ans[i][j]+=1ll*k*a[i][j])>ans[x][y])x=i,y=j;
	printf("%d %d\n",x,y);
}
signed main(){
	int t=1;
	//	scanf("%d",&t);
	while(t--)
		Yorushika();
}
```v
</details>
posted @   yinhee  阅读(7)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战

阅读目录(Content)

此页目录为空

点击右上角即可分享
微信分享提示