链接:https://ac.nowcoder.com/acm/contest/5158/D
来源:牛客网
牛妹为了打比赛经常不吃饭,但是牛妹非常喜欢吃豆子,她经常会吃很多很多的豆子,所以牛妹不会感觉到饿, 自然就不想吃饭了。
现在牛妹有一个 n∗m个格子的棋盘.左下角的格子坐标为 (1,1), 右上角的格子坐标为 (n,m).棋盘的每个格子都能放任意个豆子.
这时牛可乐带着一袋豆子走了过来, 打算跟牛妹分享这些豆子, 但是牛可乐并不想就这么简单的让牛妹吃到豆子, 所以牛可乐给牛妹出了一个难题.
现在牛可乐有 k 次操作,每次操作给出四个数字 x1,y1,x2,y2: 表示牛可乐会将所有满足 x1≤x≤x2,y1≤y≤y2 这两个条件的位置上放一个豆子。
牛可乐放完豆子后给出了 q次询问, 每次询问给出四个数字 x1,y1,x2,y2: 表示询问所有满足 x1≤x≤x2,y1≤y≤y2 这两个条件的位置上中总共有多少个豆子.
这个问题可难住牛妹了, 牛妹想要吃到豆子就必须答对牛可乐的所有询问。
这个题要求两次前缀和,一次前缀和是求改变后的数组,令一次的前缀和是为了o1的查询
#include<iostream> #include<algorithm> using namespace std; typedef long long ll; const int maxn=2100; int n,m,k,q; ll a[maxn][maxn]; ll s[maxn][maxn]; ll ans[maxn][maxn]; int main(){ scanf("%d%d%d%d",&n,&m,&k,&q); for(int i=1;i<=k;i++){ int x1,y1,x2,y2; scanf("%d%d%d%d",&x1,&y1,&x2,&y2); a[x1][y1]++; a[x1][y2+1]--; a[x2+1][y1]--; a[x2+1][y2+1]++; } for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ s[i][j]=a[i][j]+s[i-1][j]+s[i][j-1]-s[i-1][j-1]; } } for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ ans[i][j]=s[i][j]+ans[i-1][j]+ans[i][j-1]-ans[i-1][j-1]; } } while(q--){ int x1,y1,x2,y2; scanf("%d%d%d%d",&x1,&y1,&x2,&y2); printf("%lld ",ans[x2][y2]-ans[x1-1][y2]-ans[x2][y1-1]+ans[x1-1][y1-1]); } return 0; }