luoguP6070 [MdOI2020] Decrease 贪心+二维差分
显然从左到右,从上到下依次处理每个格子步数是最少的.
而由于我们的顺序是固定的,每次操作等于是一个区间修改,单点查询.
利用二维差分的方式可以轻松实现.
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; }