[2018雅礼集训1-16]方阵

[题目描述]:

给出一个 \(n×m\) 大小的矩形,每个位置可以填上$ [1,c]$中的任意一个数,要求填好后任意两行互不等价且任意两列互不等价,两行或两列等价当且仅当对应位置完全相同,求方案数 。

\(n,m\le 5000\)

确实是一道神仙题。

对这种行列都有限制的题我们可以先只考虑一边。

我们先只考虑让行之间互不等价,一个\(n行m列\)且行互不等价的矩形的方案数为\((C^m)^{\underline{n}}\)。

我们设\(g(m)\)表示行互不等价的情况下,\(m\)列的矩形的方案数。\(g(m)=(C^m)^{\underline{n}}\)。

我们设\(f(m)\)表示行和列都分别互不等价的情况下,\(m\)列的矩形的方案数,也就是我们要的答案。

则:
\[
g(m)=\sum\limits_{i=0}^m\begin{Bmatrix}m\\i \end{Bmatrix}f(i)
\]
这个式子的意义就是我们枚举\(m\)列分成了\(i\)个互不等价的集合,再将这\(m\)列分配到这些集合中去。

由斯特林反演得到:
\[
f(m)=\sum\limits_{i=0}^m(-1)^{m-i}\begin{bmatrix}m\\i \end{bmatrix}g(i)
\]
于是我们就可以\(O(n^2)\)计算了。

代码:

#include<bits/stdc++.h>
#define ll long long
#define mod 1004535809
#define N 5005

using namespace std;
inline int Get() {int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}while('0'<=ch&&ch<='9') {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}return x*f;}

int T;
ll n,m,c;
ll s1[N][N],g[N];
int main() {
    s1[0][0]=1;
    for(int i=1;i<=5000;i++)
        for(int j=1;j<=5000;j++)
            s1[i][j]=(s1[i-1][j-1]+(i-1)*s1[i-1][j])%mod;
    T=Get();
    while(T--) {
        n=Get(),m=Get(),c=Get();
        g[0]=1;
        for(int i=1;i<=m;i++) g[i]=g[i-1]*c%mod;
        ll ans=0;
        int flag=m&1?1:-1;
        for(int i=1;i<=m;i++,flag*=-1) {
            ll now=1;
            for(int j=1;j<=n;j++) now=now*(g[i]-j+1+mod)%mod;
            (ans+=flag*s1[m][i]*now%mod+mod)%=mod;
        }
        cout<<ans<<"\n";
    }
    return 0;
}

原文地址:https://www.cnblogs.com/hchhch233/p/10016522.html

时间: 2024-10-08 14:26:29

[2018雅礼集训1-16]方阵的相关文章

#6030. 【雅礼集训 2017 Day1】矩阵

#6030. 「雅礼集训 2017 Day1」矩阵 题目描述 有一个 n×n  的矩阵,每个位置 (i,j) 如果是 . 表示为白色,如果是 # 表示为黑色. 初始时,每个位置可以是黑色或白色的,(i,j)  位置的值会作为 ai,j 给你. 现在有一种操作,选择两个整数 i,j∈[1,n],记 (i,1),(i,2),…,(i,n) (i, 1), (i, 2)的颜色为 C1,C2,…Cn ??,将 (1,j),(2,j),…,(n,j)  的颜色赋为 C1,C2,…,Cn ??. 你的任务是

2018雅礼 折射

雅礼题好难啊. 这个DP题思路好强. 这个东西首先一眼就知道按y排的DP怎么写,大概就是设$f(i,j,k)$表示考虑到y坐标从大到小排名为i的点,这线上一次转是j,上上次转是k的数量,直接二维限制转移就行了. 考虑这东西怎么优化. 前缀和能搞时间,woc空间也被卡了??? 打出来表看一看???? 这个DP数组有好多都是空的... 因为越往后x限制的越少. 然后我就不会了. 正经:设$f(i,0/1)$表示从x坐标排名为i,出门左转还是右转的线的数量. 我一开始就否掉了这东西因为好像转移顺序会出

雅礼集训——day1、day2

day1: 嗯上午考试拿了100分.第一题40,第二题60.看完题的时候我就觉得第二题的部分分是最好得到的,因为数据范围只有300,而且一眼看上去就是网络流的二分图多重匹配模型?然后就建了个网络流写了些,期望得分是70分,但是第1组数据有点劲,被卡掉了,就拿了60分.正解是map+set的贪心...并不会STL 写完T2去看T1,先用DFS乱搞了一下,结果样例都没过去,我手推了一下样例,得到了一个公式,就是从一个点出发需要加上的边数=这个点通过DFS能够遍历到的点的个数-与这个点直接相连的点的个

「6月雅礼集训 2017 Day5」吃干饭

[题目大意] 询问[L,R]中选若干个数异或起来得到的答案集合大小.多组数据. 对于50%的数据,$R - L \leq 10^4$ 对于100%的数据,$R - L \leq 10^{18}, T \leq 10^2$ [题解] 考虑50%的数据,暴力线性基即可. 这样的复杂度是$O(T(R-L)logn)$ 观察到数据比较特殊,是连续的一段正整数,我们写完线性基暴力然后打个表观察数在什么时候被插入到线性基里. 我们以[23333, 66666]为例: 首先L=23333,这个数一定被插入到线

雅礼集训 2017 Day2

水箱 loj6032 先分析一波考试时乱搞搞 对于 20% 的数据,n,m≤16: 暴力枚举每个条件是否满足,然后检查,复杂度O(2m) (然而我太菜了,这都能打错) 对于另外 10% 的数据,只存在指明某处有水的条件: 水箱的高度是无限的,所以无论条件给出的y有多大,均能满足,直接输出m 原文地址:https://www.cnblogs.com/XYZinc/p/8603852.html

雅礼集训 Day6

今日得分:10+0+20=30,修改后90+90+100=280 今日题解: T1:题中所给的结构构成一个内向环套树森林,对于每棵环套树,首先树上的每个点的孩子只能留一个最大的,其他的都需要修改,处理后变为一个环上面连一些链,每个链可以断开链首或者断开环上的前驱节点,并且至少要断开一条环上的边,特判只有一个环的情况即可 T2:一个位置如果先吃掉左边的三明治,那么它左边的位置也会先吃左边,于是我们对于每一行的都搜一遍即可 T3:如果所有操作都是在1~n区间内进行,那么它的实际作用就是去掉最大值再加

loj6029 「雅礼集训 2017 Day1」市场

传送门:https://loj.ac/problem/6029 [题解] 考虑如果有一些近似连续的段 比如 2 2 2 3 3 3,考虑在除3意义下,变成0 0 0 1 1 1,相当于整体-2 又:区间增加很容易造成这种段,所以我们猜测可以暴力维护 用一棵线段树即可.(好像真的能暴力维护啊 我不知道怎么证明复杂度) # include <stdio.h> # include <string.h> # include <iostream> # include <al

雅礼集训——day3、day4

day3: 上午考试就拿了10分... T1写了个N^3的暴力,然后就拿了10分...正解是要二分时间然后找到前m个脚,然后用二分套二分求第k大.... T2看了半天感觉并不可做...然后正解居然要用斐波拉契数列的通项来求解.... T3求最小生成树的个数,我以为这道题还是可以拿50分的,然后就没有然后了.推了2小时的样例然后强行把自己劝退了...正解是要用字母树+贪心... 要学的东西又多了好多,压力好大... 下午讲的字符串算法,最后的那个回文树不是很明白...这两天得学一下字符串算法 da

「6月雅礼集训 2017 Day10」quote

[题目大意] 一个合法的引号序列是空串:如果引号序列合法,那么在两边加上同一个引号也合法:或是把两个合法的引号序列拼起来也是合法的. 求长度为$n$,字符集大小为$k$的合法引号序列的个数.多组数据. $1 \leq T \leq 10^5, 1 \leq n \leq 10^7, 1\leq K \leq 10^9$ [题解] 显然引号序列可以看做括号序列,于是我们有了一个$O(n^2)$的dp了. 设$f_{i,j}$表示到第$i$个位置,前面有$j$个左引号没有匹配,的方案数 每次,要么有