-
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; }
D - Dull Chocolates Gym - 101991D -离散化-前缀和
最新推荐文章于 2024-02-13 13:52:16 发布