zoukankan      html  css  js  c++  java
  • BZOJ5010: [Fjoi2017]矩阵填数

    h<=10000 * w<=10000的矩阵,每个格填不超过m<=10000的数,外加n<=10的限制,描述n个子矩阵中最大值一定要是多少,求方案数。

    首先一块地能填的数就是1~这块地经过多重矩形覆盖后的最小值,然后要排除那些规定矩形填不到最大值的情况,所以答案为:每块地都满足<=该块地被限制矩形覆盖后的最小值的方案-所有一块地<该块地被限制矩形覆盖后的最小值的方案(即“某一个一定不满足条件的方案”)+所有两块地<该块地被限制矩形覆盖后的最小值的方案(即“某两个一定不满足条件的方案”)-+-+……,就是容斥。

    由于要进行矩形的覆盖并且统计每个数据出现的次数来计算答案,就把坐标离散化一波,并把离散化后切成的每一块矩形的面积处理出来。为了方便,把按离散化后坐标切成的矩形标记为左开右闭(或左闭右开)。

     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<stdlib.h>
     4 #include<algorithm>
     5 //#include<iostream>
     6 using namespace std;
     7  
     8 int h,w,m,n;
     9 int xx[23],yy[23],vv[23],lx=0,ly=0,lv=0;
    10 struct mat{int x1,x2,y1,y2,v;}a[23];
    11 const int mod=1e9+7;
    12 int mp[23][23],re[23][23],cnt[23];
    13 int powmod(int a,int b)
    14 {
    15     int ans=1,tmp=a;
    16     while (b) {if (b&1) ans=1ll*ans*tmp%mod;tmp=1ll*tmp*tmp%mod;b>>=1;}
    17     return ans;
    18 }
    19 int t;
    20 int main()
    21 {
    22     scanf("%d",&t);
    23     while (t--)
    24     {
    25         scanf("%d%d%d%d",&h,&w,&m,&n);
    26         xx[lx=1]=0;xx[lx=2]=h;
    27         yy[ly=1]=0;yy[ly=2]=w;
    28         vv[lv=1]=m;
    29         for (int i=1;i<=n;i++)
    30         {
    31             scanf("%d%d%d%d%d",&a[i].x1,&a[i].y1,&a[i].x2,&a[i].y2,&a[i].v);
    32             a[i].x1--;a[i].y1--;
    33             xx[++lx]=a[i].x1;xx[++lx]=a[i].x2;
    34             yy[++ly]=a[i].y1;yy[++ly]=a[i].y2;
    35             vv[++lv]=a[i].v;vv[++lv]=a[i].v-1;
    36         }
    37         sort(xx+1,xx+1+lx);sort(yy+1,yy+1+ly);sort(vv+1,vv+1+lv);
    38         lx=unique(xx+1,xx+1+lx)-xx-1;ly=unique(yy+1,yy+1+ly)-yy-1;lv=unique(vv+1,vv+1+lv)-vv-1;
    39         for (int i=1;i<=lx;i++)
    40             for (int j=1;j<=ly;j++)
    41                 re[i][j]=(xx[i]-xx[i-1])*(yy[j]-yy[j-1]);
    42         for (int i=1;i<=n;i++)
    43         {
    44             a[i].x1=lower_bound(xx+1,xx+1+lx,a[i].x1)-xx;
    45             a[i].y1=lower_bound(yy+1,yy+1+ly,a[i].y1)-yy;
    46             a[i].x2=lower_bound(xx+1,xx+1+lx,a[i].x2)-xx;
    47             a[i].y2=lower_bound(yy+1,yy+1+ly,a[i].y2)-yy;
    48             a[i].v=lower_bound(vv+1,vv+1+lv,a[i].v)-vv;
    49         }
    50         int ans=0;
    51         for (int s=0;s<(1<<n);s++)
    52         {
    53             for (int j=1;j<=lx;j++)
    54                 for (int k=1;k<=ly;k++)
    55                     mp[j][k]=lv;
    56             int now=1;
    57             for (int i=1;i<=n;i++)
    58             {
    59                 int v=a[i].v;
    60                 if ((s>>(i-1))&1) now=-now,v--;
    61                 for (int j=a[i].x1+1;j<=a[i].x2;j++)
    62                     for (int k=a[i].y1+1;k<=a[i].y2;k++)
    63                         mp[j][k]=min(mp[j][k],v);
    64             }
    65             memset(cnt,0,sizeof(cnt));
    66             for (int i=1;i<=lx;i++)
    67                 for (int j=1;j<=ly;j++)
    68                     cnt[mp[i][j]]+=re[i][j];
    69             for (int i=1;i<=lv;i++) if (cnt[i]) now=1ll*now*powmod(vv[i],cnt[i])%mod;
    70             ans=(ans+now)%mod;
    71         }
    72         printf("%d
    ",(ans+mod)%mod);
    73     }
    74     return 0;
    75 }
    76 
    View Code
  • 相关阅读:
    Spring框架基本应用
    hibernate 多表查询
    myeclipse 中解决Hibernate 和Struts 2的冲突
    新建一个Tomcat服务器
    hibernate连接数据库
    MyEclipse从数据库逆向生成Hibernate实体类
    Struts 2 标签
    struts 2 框架的应用
    AutoIt: WinGetClassList可以把当前窗口所有的handle全部列出来
    自动化测试建议【转载,与我的想法完全雷同】
  • 原文地址:https://www.cnblogs.com/Blue233333/p/7504701.html
Copyright © 2011-2022 走看看