题面:
算法:对一个“斜着的”数组差分!
题解:
对一个三角形斜着打标记(差分),对此数组进行差分!
代码如下:
1、81分(47分稳过,两组数据卡常,lemon会自动重测!)
算法:对一维进行差分,另一维暴力修改(一维差分很好写,也不难想)
注意:min(,)!!!
否则如果超出了n还去修改,可能 就 会RE! 对拍了一个小时,一直RE!!!
代码如下:
(如果你没有得到81分,① 自己写读优,这样就可以让lemon自动重测!② 可能老师忘记开O2了!)
#include <cstdio>
#include <iostream>
#include <cmath>
#include <cctype>
#include <queue>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#define ll long long
#define N 1005
using namespace std;
struct node
{
int a,b,c,d;
}e[300005];
ll aa[N][N];
ll sum[N][N];
inline int read()
{
int X=0,w=0; char ch=0;
while(!isdigit(ch)) {w|=ch=='-';ch=getchar();}
while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
return w?-X:X;
}
int main()
{
freopen("u.in","r",stdin);
freopen("u.out","w",stdout);
//printf("%d\n",(sizeof(aa)+sizeof(sum)+sizeof(e))/1024/1024);
int n,m;
//scanf("%d%d",&n,&m);
n=read(),m=read();
for(int i = 1;i <= m;i++)
{
e[i].a=read(),e[i].b=read(),e[i].c=read(),e[i].d=read();
//scanf("%d%d%d%d",&e[i].a,&e[i].b,&e[i].c,&e[i].d);
}
if(m==0)
{
puts("0");
return 0;
}
//printf("%d\n",e[2979].b);
for(int i = 1;i <= m;i++)
{
int a,b,c,d;
a=e[i].a,b=e[i].b,c=e[i].c,d=e[i].d;
ll tt=1;
for(int j = a;j < min(a+c,n+1);j++)
{
/*if(b==1||b+tt==1)
{
int u=1;
if(j==12)
{
u=2;
}
}*/
aa[j][b]+=d;
if(tt+b>n||tt>n) continue;
aa[j][b+tt]-=d;
/*if(aa[12][1]<0)
{
printf("%d %d %d\n",i,j,tt);
printf("%d\n",e[i].b);
for(int z =1;z <= 12;z++)
{
for(int o = 1;o <= 5;o++)
{
printf("%d ",aa[z][o]);
}
puts("");
}
int qwe=1;
qwe=2;
return 0;
}*/
tt++;
}
}
for(int i = 1;i <= n;i++)
{
for(int j = 1;j <= n;j++)
{
sum[i][j]=sum[i][j-1]+aa[i][j];
/*if(sum[i][j]<0)
{
printf("%d %d\n",i,j);
return 0 ;
}*/
}
}
ll ans=sum[1][1];
//printf("%d \n",sum[12][1]);
for(int i = 1;i <= n;i++)
{
for(int j = 1;j <= n;j++)
{
if(i==1&&j==1) continue;
ans^=sum[i][j];
}
}
printf("%lld\n",ans);
return 0 ;
}
2、AC
时间复杂度
#include<bits/stdc++.h>
#define ll long long
#define N 1005
using namespace std;
int n,q;
ll a[N][N],sum[N][N],ans;
void add_a(int x,int y,int w)
{
if(x<=n&&y<=n) a[x][y]+=w;
}
void add_b(int x,int y,int w)
{
if(x<=n&&y<=n) sum[x][y]+=w;
}
int main()
{
freopen("u.in","r",stdin);
freopen("u.out","w",stdout);
scanf("%d%d",&n,&q);
while(q--)
{
int r,c,l,s;
scanf("%d%d%d%d",&r,&c,&l,&s);
add_a(r,c,s);
add_a(r+l,c+l,-s);
add_b(r+l,c,-s);
add_b(r+l,c+l,s);
}
for(int i = 1;i <= n;i++)
{
for(int j = 1;j <= n;j++)
{
if(i>1) a[i][j]+=a[i-1][j-1]+a[i-1][j]-a[i-2][j-1];
else a[i][j]+=a[i-1][j-1]+a[i-1][j];
sum[i][j]+=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1];
ans^=(a[i][j]+sum[i][j]);
}
}
printf("%lld\n",ans);
return 0;
}