显然从左到右,从上到下依次处理每个格子步数是最少的.
而由于我们的顺序是固定的,每次操作等于是一个区间修改,单点查询.
利用二维差分的方式可以轻松实现.
code:
#include <cstdio>
#include <cstring>
#include <string>
#include <vector>
#include <algorithm>
#define N 5003
#define ll long long
#define setIO(s) freopen(s".in","r",stdin)
using namespace std;
ll mat[N][N],sum[N][N],det[N][N];
int main()
{
// setIO("input");
int i,j,n,m,k;
scanf("%d%d%d",&n,&m,&k);
for(i=1;i<=m;++i)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z),mat[x][y]+=z;
}
ll ans=0;
for(i=1;i<=n;++i)
{
for(j=1;j<=n;++j)
{
sum[i][j]+=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1];
if(i+k-1<=n&&j+k-1<=n)
{
ll cur=mat[i][j]+sum[i][j];
ans+=abs(cur);
sum[i][j]-=cur;
sum[i+k][j]+=cur;
sum[i][j+k]+=cur;
sum[i+k][j+k]-=cur;
}
}
}
int flag=1;
for(i=1;i<=n;++i)
{
for(j=1;j<=n;++j) if(mat[i][j]+sum[i][j]) flag=0;
}
printf("%lld\n",flag?ans:-1);
return 0;
}