RT,赛时代码,只能过小样例
#include<bits/stdc++.h>
//#define int ll
#define pb push_back
#define mp make_pair
#define sec second
#define fir first
#define pii pair<int,int>
#define piii pair<int,pair<int,int> >
using namespace std;
typedef long long ll;
const int N=2005;
const int inf=(1<<30)-1;
const ll inff=1ll<<60;
const int mod=1e9+7;
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^48);c=getchar();}
return x*f;
}
int n,m,a[N][N],all,bac[N],lit,row;
void output(int x,int y){
// printf("x,y:%d %d\n",x,y);
printf("%d ",a[x][y]);
if(x == all && y == bac[all]) return;
if(x<n) output(x+1,y);
else{
if(y==1 || x==all){
row++;
if(bac[lit] < row) lit++;
output(lit,row);
}
else output(x+1,y-1);
}
}
void out(){
for(int i=1;i<=all;i++)
for(int j=1;j<=bac[i];j++)
printf("%d%c",a[i][j],j==bac[i]?'\n':' ');
}
int main(){int tests=1;//tests=read();
while(tests--){
// freopen("a.in","r",stdin);
// freopen("a.txt","w",stdout);
n=read(),m=read();
all=2*n-1;
for(int i=1;i<=all;i++)
bac[i]=2*n-1-abs(n-i);
// for(int i=1;i<=all;i++) printf("i:%d bac:%d\n",i,bac[i]);
for(int i=1;i<=m;i++){
int x=read(),y=read(),z=read(),r=read(),k=read();
if(x==0){
x=n-y;
y=n-z;
}
else if(y==0){
x=n+x;
y=n-z;
}
else{
int tmp=n+x;
x=n-y;
y=tmp;
}
// printf("centre %d %d\n",x,y);
// 找到每次操作对应的中心点
// r 是 半径,tim 是处理的层数
// 问题应该就在下面差分这块,但不知道错在哪了
r--;
int le=x-r,ri=x+r;
int len=ri-le+1,tim=1;
if(le<1){
tim += 1-le;
le=1;
}
if(ri>all) ri=all;
// int bl=y-r,br=y,mid=0;
int bl,br;
if(x <= n) bl=y-r,br=y;
else br=y+(x-max(le,n)),bl=br-r;
// 求第一层的左右端点
for(int i=le;i<=ri;i++){
// printf("i:%d bl:%d br:%d\n",i,bl,br);
a[i][max(1,bl)]+=k;
a[i][min(bac[i],br)+1]-=k;
if(i<n){
if(tim<=len/2) br++;
else bl++;
}
else{
if(tim<=len/2) bl--;
else br--;
}
// 移动左右端点,在 i<n 时左移,i>n 时右移
tim++;
}
}
for(int i=1;i<=all;i++)
for(int j=1;j<=bac[i];j++)
a[i][j] += a[i][j-1];
row=lit=1;
output(1,1); //应该没问题的输出
// out();
} return 0;
}
/*
4 3
0 1 1 3 4
3 0 3 4 3
1 0 0 2 2
*/