CF263E
小丑,做这种题做半天。
首先发现有贡献的位置是一个斜正方形,从内到外贡献系数依次递减。先拆成四个部分(四个直角三角形),每次将整个矩形旋转来分别做,最后简单容斥一下。
考虑对于一个直角三角形怎么计算贡献。考虑从它左边的一个三角形转移过来。设定点为
细节挺多。因为做法比较烂/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>