HDU 6314(容斥原理)

Matrix

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 332768/332768 K (Java/Others)
Total Submission(s): 290    Accepted Submission(s): 72


 

Problem Description

Samwell Tarly is learning to draw a magical matrix to protect himself from the White Walkers.
the magical matrix is a matrix with n rows and m columns, and every single block should be painted either black or white.
Sam wants to know how many ways to paint the matrix, satisfied that the final matrix has at least A rows, B columns was painted completely black. Cause the answer might be too big, you only need to output it modulo 998244353.

 

 

Input

There might be multiple test cases, no more than 5. You need to read till the end of input.
For each test case, a line containing four integers n,m,A,B.
1≤n,m,A,B≤3000.

 

 

Output

For each test case, output a line containing the answer modulo 998244353.

 

 

Sample Input

 

3 4 1 2

 

 

Sample Output

 

169

 

 

Source

2018 Multi-University Training Contest 2

 容斥原理。

假设不考虑列,只看行,我们令行容斥系数为fa(j)

那么

ans=\sum_{j=a}^{n}\left ( fa[j]*C_{n}^{j}*2^{n-j} \right )

意思就是,我枚举至少染了j行黑色的答案,那么显然是C_{n}^{j}*2^{n-j},通过容斥系数,我得到的是刚刚好染了j行黑色的答案

那么接下来的问题就变成了,怎么求这个容斥系数

可以这么考虑,每个刚刚好染了j行黑色的答案在总答案中只能出现一次,那么,我只要统计前面的情况中,这个答案出现了多少次,假如为sum,那么,我的fa(j)=1-sum即可

对于一个。我们可以这么想,在j的答案中,一定包含了“至少k行被染色”的答案,那么,这个数目相当于是我在确定染色的j行中选择k行,然后在乘上容斥系数,就是在k的答案中j的答案个数。

那么,我们最后可以得到这样一个等式:fa[j]=1-\sum_{k=a}^{j-1}(C_{j}^{k}*fa[k])

对于列的情况,其实是类似的。

最后我们只要nm枚举(i,j),计算一下对应项的乘积就可以出结果了。

 

一切看起来都是这么的顺利,一气呵成。

然而。。。。。。

HDU 6314(容斥原理)_第1张图片

妈耶,这么优秀的做法也能T成智障????

通过不断的降低取模次数(比如不对负数取模变回正数,而是最后答案如果为负数的时候变为正数),以及良好的C语言编码风格(没错就是在外面定义好循环的变量i,j,k),身残志坚的老年人终于

卡着时间过去。。。。。。

小小的吐槽一下,这个1s的时限真的大丈夫吗- =

#include 
#define fir first
#define se second
#define mp make_pair
#define pb push_back
#define ll long long
using namespace std;
const int maxn=3000+10;
const ll mod=998244353;
const double eps=1e-7;
const int maxm=1e6+10;
const int inf=0x3f3f3f3f;
//怕炸空间没敢开long long 
int c[maxn][maxn];   //组合数
int p[maxn*maxn];   //2的倍数
int g[maxn][maxn];
int n,m,a,b;
int i,j,k;
void init(){
    for (i=0;i

 

 

你可能感兴趣的:(hdu)