1. 程式人生 > >D - Dull Chocolates Gym - 101991D -離散化-字首和

D - Dull Chocolates Gym - 101991D -離散化-字首和

  •  
  • 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;
    }
    
  •  
  •