2020.2.16普及C組 方格紙(square【紀中】【差分】【前綴和】

正解:前綴和+二維差分

普及一波 差分:

差分其實就是前綴和的逆運算;

給你一個數組a[5]=12345a[5]={1,2,3, 4,5};差分數組b[5]=11111b[5]={1,1,1,1,1};顯然差分數組b[i]=a[i]a[i1]b[i]=a[i]-a[i-1];

那麼我們可以推出,a[1]=b[1],a[2]=b[1]+b[2]b[i]a[1]=b[1],a[2]=b[1]+b[2]…b[i]的前綴和等於a[i]a[i],這也是爲什麼說差分就是前綴和的逆運算;

知道了這個,差分還有個運用;就是在區間[l,r][l,r]進行加數操作,然後問你某個位置在操作完後的值是多少;


二維差分和一維差分本質上是一樣的
就是把 aa 數組x1,y1,x2,y2x1,y1,x2,y2的四個角賦值爲 111-1

代碼:

a[x1][y1]++;
a[x2+1][y2+1]++;
a[x1][y2+1]--;
a[x2+1][y1]--;

這樣就能做出來啦!

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
long long f[3500][3500],a[3500][3500]; 
long long n,m,x,y,x1,y1,x2,y2;
int main()
{
	freopen("square.in","r",stdin);
	freopen("square.out","w",stdout);
	scanf("%lld",&n);
    for(int i=1; i<=n; i++)
     {
     	scanf("%lld %lld %lld %lld",&x1,&y1,&x2,&y2);
        a[x1][y1]++;                 //差分
        a[x2+1][y2+1]++;
        a[x1][y2+1]--;
        a[x2+1][y1]--;
     }
    for(int i=1; i<=3000; i++)
     for(int j=1; j<=3000; j++)
       f[i][j]=f[i-1][j]+f[i][j-1]-f[i-1][j-1]+a[i][j];  //前綴和
    cin>>m;
    for(int i=1; i<=m; i++)
     {
     	scanf("%lld %lld",&x,&y);
        printf("%lld\n",f[x][y]);
     }
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章