G - Snake Rana-状压-容斥

  • G - Snake Rana
  • 假设K=3,也就是说有3个黑色的单位正方形,我们不妨设这三个黑色单位正方形是A,B和C。
  •            所有矩形的数目 =
               - 包含A的矩形数目 - 包含B的矩形数目 - 包含C的矩形数目  
               + 包含AB的矩形数目 + 包含BC的矩形数目 + 包含CA的矩形数目
               - 包含ABC的矩形数目
    
  • 于是我们要解决的问题简化为:对于任意黑色单位正方形的集合S,如何计算包含S的矩形数目。
  • 我们知道只要确定矩形上边界、下边界、左边界和右边界的位置,就唯一确定了一个矩形。
  •  
  • 如图所示 所有可能 为 :2x2x2x2=16个。
  • #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    ll n,m,k,r[35],c[35],tot;
    ll hi,lw,lt,rt,sum,ans,t;
    int main()
    {
        scanf("%lld",&t);
        while(t--)
        {
            scanf("%lld%lld%lld",&n,&m,&k);
            for(int i=0; i<k; i++)
                scanf("%lld%lld",&r[i],&c[i]);
            ans=n*(n+1)*m*(m+1)/4;
            tot=(1<<k);
            for(int i=1; i<tot; i++)
            {
                int cnt=0;
                hi=rt=0;
                lw=lt=0x7f7f7f7f;
                for(int j=0; j<k; j++)
                {
                    if((1<<j)&i)
                    {
                        cnt++;
                        hi=max(hi,c[j]),lw=min(lw,c[j]),lt=min(lt,r[j]),rt=max(rt,r[j]);
                    }
                }
                sum=(m-hi+1)*(n-rt+1)*lw*lt;
                if(cnt%2)ans-=sum;
                else ans+=sum;
            }
            printf("%lld\n",ans);
        }
        return 0;
    }
    

猜你喜欢

转载自blog.csdn.net/BePosit/article/details/85221434