P3813 [FJOI2017]矩阵填数(组合数学)
shadowice1984说:看到计数想容斥........
这题中,我们把图分成若干块,每块的最大值域不同
蓝后根据乘法原理把每块的方案数(互不相干)相乘。
怎么计算每块方案数呢
把子矩阵按最大值从小到大排序
暴力预处理好每$k(1<=k<=n)$个矩阵之间的交集、并集
设最大值为$v$的位置的集合大小为$S$
那么我们算出来(本层)的结果就是v^{|S|}
然鹅我们并没有减去某些矩阵没有到最大值(最大只取到$v-1$)的情况
于是对于每个最大值为$v$的子矩阵在$S$中的部分$T$,我们要减去$(v-1)^{|T|}*v^{|S-T|}$
但是我们又发现,多减去了某2个子矩阵都没有到最大值的情况,于是我们就把它加起来
再减去3个子矩阵都没到最大值的情况
.............
这就是容斥原理辣
“最大值为$v$的位置的集合大小为$S$”,这个咋算呢
$|S|=($最大值$<=v$的位置的集合大小)$-$(最大值$<v$的集合大小),$T$同理。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int mod=1e9+;
inline ll Min(ll a,ll b){return a<b?a:b;}
inline ll Max(ll a,ll b){return a>b?a:b;}
ll Pow(ll x,ll y){
ll re=;
for(;y;y>>=,x=x*x%mod)
if(y&) re=re*x%mod;
return re;
}
struct Matrix{
ll xl,yl,xr,yr,v;
bool operator < (const Matrix &tmp) const{return v<tmp.v;}
void operator &= (const Matrix &tmp) {
xl=Max(xl,tmp.xl), xr=Min(xr,tmp.xr);
yl=Max(yl,tmp.yl), yr=Min(yr,tmp.yr);
}
inline void init(){
scanf("%lld%lld%lld%lld%lld",&xl,&yl,&xr,&yr,&v);
}
inline bool null(){return xl>xr||yl>yr;}
inline ll area(){return (xr-xl+)*(yr-yl+);}
}a[],p;
int T,m,n,uni[],ist[],siz[];ll h,w;
void Solve(){
memset(uni,,sizeof(uni));
scanf("%lld%lld%d%d",&h,&w,&m,&n);
for(int i=;i<n;++i) a[i].init();
sort(a,a+n); int Mx=(<<n)-;
for(int i=;i<=Mx;++i){//暴力处理交集
p.xl=;p.yl=;p.xr=h;p.yr=w;
for(int j=,u=i;!p.null()&&u;u>>=,++j)
if(u&) p&=a[j];
ist[i]=p.null()?:p.area();
}
for(int i=;i<=Mx;++i)//暴力处理并集
for(int j=i;j;j=(j-)&i)
uni[i]+=((siz[j]&)?:-)*ist[j];
int nw=,ls=;
ll sum,tot,re,k,ans=Pow(m,h*w-uni[Mx]);
for(int i=;i<n;++i){//分层处理最大值为$a[i].v$的块的方案数
nw|=(<<i);
if(a[i].v==a[i+].v) continue;
sum=uni[nw|ls]-uni[ls];
re=Pow(a[i].v,sum);
for(int u=nw;u;u=(u-)&nw){
tot=uni[u|ls]-uni[ls];
k=Pow(a[i].v-,tot)*Pow(a[i].v,sum-tot)%mod;
if(siz[u]&) re=(re-k+mod)%mod;
else re=(re+k)%mod;
}ans=ans*re%mod; ls|=nw; nw=;
}printf("%lld\n",ans);
}
int main(){
for(int i=;i<=;++i) siz[i]=siz[i>>]+(i&);
scanf("%d",&T);
while(T--) Solve();
return ;
}
P3813 [FJOI2017]矩阵填数(组合数学)的更多相关文章
- [luogu P3813] [FJOI2017] 矩阵填数 解题报告 (容斥原理)
题目链接: https://www.luogu.org/problemnew/show/P3813 题目: 给定一个 h*w的矩阵,矩阵的行编号从上到下依次为 1..h,列编号从左到右依次1..w. ...
- P3813 [FJOI2017]矩阵填数
传送门 矩阵很大,但是发现 $n$ 很小,从这边考虑,对于一个一堆小矩阵放在一起的情况 考虑把每一块单独考虑然后方案再乘起来 但是这些奇怪的东西很不好考虑 所以暴力一点,直接拆成一个个小块 但是这样我 ...
- [FJOI2017]矩阵填数——容斥
参考:题解 P3813 [[FJOI2017]矩阵填数] 题目大意: 给定一个 h∗w 的矩阵,矩阵的行编号从上到下依次为 1...h ,列编号从左到右依次 1...w . 在这个矩阵中你需要在每个格 ...
- [BZOJ5010][FJOI2017]矩阵填数(状压DP)
5010: [Fjoi2017]矩阵填数 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 90 Solved: 45[Submit][Status][ ...
- bzoj5010: [Fjoi2017]矩阵填数
Description 给定一个 h*w 的矩阵,矩阵的行编号从上到下依次为 1..h,列编号从左到右依次1..w.在这个矩阵中你需要在每 个格子中填入 1..m 中的某个数.给这个矩阵填数的时候有一 ...
- bzoj 5010: [Fjoi2017]矩阵填数
Description 给定一个 h*w 的矩阵,矩阵的行编号从上到下依次为 1..h,列编号从左到右依次1..w.在这个矩阵中你需要在每 个格子中填入 1..m 中的某个数.给这个矩阵填数的时候有一 ...
- BZOJ5010 FJOI2017矩阵填数(容斥原理)
如果只考虑某个子矩阵的话,其最大值为v的方案数显然是vsize-(v-1)size.问题在于处理子矩阵间的交叉情况. 如果两个交叉的子矩阵所要求的最大值不同,可以直接把交叉部分划给所要求的最大值较小的 ...
- 【BZOJ】5010: [Fjoi2017]矩阵填数
[算法]离散化+容斥原理 [题意]给定大矩阵,可以每格都可以任意填1~m,给定n个子矩阵,要求满足子矩阵内的最大值为vi,求方案数. n<=10,h,w<=1w. [题解] 此题重点之一在 ...
- [FJOI2017]矩阵填数
[Luogu3813] [LOJ2280] 写得很好的题解 \(1.\)离散化出每一块内部不互相影响的块 \(2.\)\(dp[i][j]\)为前 \(i\) 种重叠块其中有 \(j\) 这些状态的矩 ...
随机推荐
- sql server 函数的自定义
创建用户定义函数.这是一个已保存 Transact-SQL 或公共语言运行时 (CLR) 例程,该例程可返回一个值.用户定义函数不能用于执行修改数据库状态的操作.与系统函数一样,用户定义函数可从查询中 ...
- Python解决乱码问题
解决python乱码问题 字符串在python的内部采用unicode的编码方式,因此,在做编码转换时,通常需要以unicode作为中间编码,即先将其他编码的字符串解码(decode)成unicode ...
- Serveral effective linux commands
1. 统计当前文件夹下文件个数(不包括子目录下文件): $ ls -l | grep "^-" | wc -l 2. 统计当前文件夹下文件个数(包括子目录下文件): $ ls -l ...
- iOS UI基础-8.0 UIAlertView使用
弹出框的使用 1.实现代理UIAlertViewDelegate 2.弹出框 // 弹框初始化 UIAlertView *alert = [[UIAlertView alloc] initWithTi ...
- python爬虫-基础入门-爬取整个网站《3》
python爬虫-基础入门-爬取整个网站<3> 描述: 前两章粗略的讲述了python2.python3爬取整个网站,这章节简单的记录一下python2.python3的区别 python ...
- webpack打包报错
Invalid configuration object. Webpack has been initialised using a configuration object that does no ...
- 软工网络15团队作业4——Alpha阶段敏捷冲刺2.0
软工网络15团队作业4--Alpha阶段敏捷冲刺2.0 1.提供当天站立式会议照片一张. 2.每个人的工作 成员 昨天已完成 今天计划完成 郭炜埕 熟悉微信web开发者工具 完成新建话题界面的设计 郑 ...
- wordpress学习(二)
学习如何使用wpdb<br/> <? global $wpdb; //声明wpdb类 $wpdb->show_errors(); //1.学会向数据库中数据表添加一行数据(增) ...
- spring4.0.0 源码导入eclipse(sts)
其余步骤请见:http://www.cnblogs.com/xiluhua/p/7450972.html 执行 gradle eclipse -x :eclipse 报错: 解决办法: 找到 行,注释 ...
- 使用Java函数接口及lambda表达式隔离和模拟外部依赖更容易滴单测
概述 单测是提升软件质量的有力手段.然而,由于编程语言上的支持不力,以及一些不好的编程习惯,导致编写单测很困难. 最容易理解最容易编写的单测,莫过于独立函数的单测.所谓独立函数,就是只依赖于传入的参数 ...