20181101noip模拟赛T1
思路:
我们看到这道题,可以一眼想到一维差分
但这样的复杂度是O(nq)的,显然会T
那么怎么优化呢?
我们会发现,差分的时候,在r~r+l-1的范围内
差分增加的值横坐标相同,纵坐标递增
减小的值横坐标和纵坐标都以1为公差递增
那么,我们就可以将差分数组差分
每次标记(r,c)(r,c+1),(r+l,c)(r+l,c+l)即可
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define rii register int i #define rij register int j #define int long long using namespace std; int cf1[2005][2005],cf2[2005][2005],x[2005][2005]; int n,q,r,c,l,s; inline int rd(){ int y=0,f=1;char ch=getchar(); while(!isdigit(ch)) {f=ch=='-'?0:1;ch=getchar();} while(isdigit(ch)) {y=(y<<1)+(y<<3)+ch-'0';ch=getchar();} return f?y:-y; } signed main() { freopen("u.in","r",stdin); freopen("u.out","w",stdout); n=rd(),q=rd(); for(rii=1;i<=q;i++) { r=rd(),c=rd(),l=rd(),s=rd(); cf1[r][c]+=s; cf1[r+l][c]-=s; cf2[r][c+1]+=s; cf2[r+l][c+l+1]-=s; } for(rij=1;j<=n;j++) { for(rii=1;i<=n;i++) { cf1[i][j]+=cf1[i-1][j]; } } for(rii=1;i<=n;i++) { for(rij=1;j<=n;j++) { cf2[i][j]+=cf2[i-1][j-1]; } } for(rii=1;i<=n;i++) { for(rij=1;j<=n;j++) { x[i][j]+=x[i][j-1]+cf1[i][j]-cf2[i][j]; } } int ans=0; for(rii=1;i<=n;i++) { for(rij=1;j<=n;j++) { ans^=x[i][j]; } } printf("%lld",ans); return 0; }