博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
BZOJ5010: [Fjoi2017]矩阵填数
阅读量:4660 次
发布时间:2019-06-09

本文共 2579 字,大约阅读时间需要 8 分钟。

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

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

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

1 #include
2 #include
3 #include
4 #include
5 //#include
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<
>(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\n",(ans+mod)%mod);73 }74 return 0;75 }76
View Code

 

转载于:https://www.cnblogs.com/Blue233333/p/7504701.html

你可能感兴趣的文章
python入门
查看>>
checkbox与文字对齐
查看>>
高精度模板
查看>>
iOS - OC/Swift:验证手机号/固话用正则表达式
查看>>
HTML accessKey约定俗成的标准
查看>>
Spring框架系列(六)--事务Transaction
查看>>
冯.诺依曼体系结构
查看>>
poj2492 A Bug's Life(带权并查集)
查看>>
ABAP区别CLEAR、REFRESH、FREE
查看>>
JavaScript中Web应用程序事件处理
查看>>
禅定记录 5
查看>>
restrictkeyword
查看>>
Etcd学习(一)安装和.NETclient測试
查看>>
js-xlsx操作excel表格
查看>>
HBase学习
查看>>
硬盘及其分区(0819整理)
查看>>
Font in Google Adsense
查看>>
前端模板 artTemplate之辅助方法template.helper
查看>>
java之反射
查看>>
Charles 连接手机抓包出现Unknown,一直无法抓包的问题解决
查看>>