D - Dull Chocolates Gym - 101991D -離散化-字首和
阿新 • • 發佈:2018-11-25
-
D - Dull Chocolates
- Gym - 101991D
- 題意:給定n*m的圖有k個white的方塊,其餘的全為black,問有多少點(i,j)滿足從(1,1)到(i,j)
- 這個矩形區域中white的個數為奇數個。
- 思路:有k個點,點座標的大小都在1-1e9之內,但是點的數目較小隻有1e3,所以進行離散化只需維護相對大小。
- 然後把這寫個離散化的點構成的圖進行二維字首和維護一下,按照題目定義的矩形區域預處理出每個點所構成的矩形區域的
- white的個數,因為是計算(1,1)-(n,m)閉區間內的點,所以最後在把離散化的圖上加上一個點(n+1,m+1).
- 然後就是進行計算了,遍歷離散化後的圖,遍歷到white的個數為奇數個得點時進行計算,從一個為奇數的點可以確定一片區域都為合法點,這片區域就是,當前點與下面第一個x軸大於他的點之間的距離*當前點與下面第一個y軸大於他的點之間的距離
- 所構成的合法矩形區域,這個矩形區域裡面的點的個數也就是這個矩形區域的面積,-是自己搞懂的,但還是要感謝第一個實現的人——賈隊長tql。
-
#include<bits/stdc++.h> using namespace std; #define ll long long #define maxn 1234 map<int,int>okx; map<int,int>oky; int dp[maxn][maxn]; int t,x[maxn]; int y[maxn],lsx,lsy; int prex,prey; struct node { int x,y; } a[maxn]; int main() { // freopen("dull.in","r",stdin); scanf("%d",&t); while(t--) { ll ans=0,tans,n,m,k; okx.clear(); oky.clear(); memset(dp,0,sizeof(dp)); scanf("%lld%lld%lld",&n,&m,&k); for(int i=0; i<k; i++) { scanf("%d%d",&a[i].x,&a[i].y); x[i]=a[i].x; y[i]=a[i].y; } sort(x,x+k); sort(y,y+k); lsx=unique(x,x+k)-x; lsy=unique(y,y+k)-y; for(int i=0; i<lsx; i++) okx[x[i]]=i; for(int i=0; i<lsy; i++) oky[y[i]]=i; for(int i=0; i<k; i++) dp[okx[a[i].x]][oky[a[i].y]]=1; for(int i=0; i<lsx; i++) for(int j=0; j<lsy; j++) if(i==0)dp[i][j]+=dp[i][j-1]; else if(j==0)dp[i][j]+=dp[i-1][j]; else dp[i][j]+=(dp[i-1][j]+dp[i][j-1]-dp[i-1][j-1]); x[lsx]=n+1; y[lsy]=m+1; for(int i=0; i<lsx; i++) { prex=x[i]; for(int j=0; j<lsy; j++) { prey=y[j]; if(dp[i][j]%2) ans+=(ll)(x[i+1]-prex)*(ll)(y[j+1]-prey); } } tans=(ll)(n*m)-ans; printf("%lld %lld\n",ans,tans); } return 0; }