洛谷P5542题解
题目链接:https://www.luogu.com.cn/problem/P5542
对于这道题,我们首先要知道前缀和的概念,比如下图:
定义Si,j为上图橙色部分的总和。
如上图,这题需要快速将(x1,y1),(x2,y2)中的数全部加一。
根据前缀和的定义,我们在(x1,y1)处加上一(最后再算一遍二维前缀和),它后面的数全部都加上了一,但很多不必要的也加上了一,如下图绿色部分:
于是,我们再(x1,y2+1)处减一,又变成了下图:(PS:洛谷中这道题是点,在这里,我们讨论的是格子,做题中,我们要注意)
再在(x2+1,y1)处减一,又变成了下图:
这时,我们可以看到,由于减了两次,右下角(上图蓝色区域)全部减了一,怎么办呢?再加回来(在(x2+1,y2+1)处)
这时,(x1,y1)至(x2,y2)都加上了一,并且其他没有改变。
总结步骤:
a[x1][y1]++; a[x1][y2+1]--; a[x2+1][y1]--; a[x2+1][y2+1]++;
上代码:
1 #include<cstdio> 2 using namespace std; 3 int k,n; 4 int a[2500][2500]; 5 int x1,y1,x2,y2; 6 int ans; 7 int main(){ 8 scanf("%d%d",&n,&k); 9 for(int i=1;i<=n;++i){ 10 scanf("%d%d%d%d",&x1,&y1,&x2,&y2); 11 a[x1+1][y1+1]++; 12 a[x1+1][y2+1]--; 13 a[x2+1][y1+1]--; 14 a[x2+1][y2+1]++; 15 }//为了防止越界,所以都加上了一 16 for(int i=1;i<=1005;++i) 17 for(int j=1;j<=1005;++j){ 18 a[i][j]+=a[i-1][j]+a[i][j-1]-a[i-1][j-1];//二维前缀和 19 if(a[i][j]==k)++ans;//统计答案 20 } 21 printf("%d",ans); 22 return 0; 23 }
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步