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;
}

猜你喜欢

转载自www.cnblogs.com/ztz11/p/9892345.html