【BZOJ3120】Line

Description

Wayne喜欢排队……不对,是Wayne所在学校的校长喜欢看大家排队,尤其是在操场上站方阵。
某日课间操时,校长童心大发想了一个极具观赏性的列队方案,如下:
1. 方阵排成N行,每行恰好M个学生。
2. 由于校长喜欢女孩子,所以在一行上不能有连续P个男生。
3. 由于校长喜欢女孩子,所以在校长看来,一列全是男生是不好的,全男生的列数不能超过Q。
Wayne因为感冒了所以不用参加列队,不过他看着大家排队排得不亦乐乎,于是他想知道,在男女生数目无限制的情况下,有多少种列队方案?
两种方案被视作不同,表明存在至少一个二元组(i,j)而两种方案中第i行第j列的同学性别不同。另外,因为答案可能很大,所以请把答案模10^9 + 7。

Input

输入仅一行4个正整数,依次是N,M,P,Q。

Output

输出仅一行,表示答案。

Sample Input

2 3 3 1

Sample Output

46

HINT

【数据规模和约定】
对于5%的数据,满足P = 1。
对于另外10%的数据,满足N * M <= 20。
对于另外15%的数据,满足N <= 2,M <= 10^6。
对于另外10%的数据,满足N <= 2。
对于另外20%的数据,满足N <= 4,P <= 2,Q <= 2。
对于100%的数据,满足1 <= N <= 8,1 <= M <= 10^18,1 <= P <= 3,0 <= Q <= 3。

题解:刚看到题,第一反应是状压+矩乘,不过算了算矩阵的大小有点难以接受。不过读了读题,发现行与行之间是互不影响的,所以我们只需要知道每一列男生女生的个数即可。

用f[i][a][b][c]表示第i列有a行有连续0个男生,b行有连续1个男生,n-a-b行有连续2个男生,已经有c行全是男生的方案数,然后把后面那3维压一压变成矩阵就可以用矩乘来优化了。

注意:a+b>n的情况显然不合法,把它扔掉可以压缩矩阵大小;矩乘时特判如果该位置为0,则不进行计算,居然会快很多。

#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
typedef long long ll;
const int P=1000000007;
int n,p,q,tot;
ll m,ans;
struct M
{
int v[200][200];
M () {memset(v,0,sizeof(v));}
int * operator [] (int a) {return v[a];}
inline M operator * (const M &b) const
{
M c;
register int i,j,k;
for(i=1;i<=tot;i++) for(k=1;k<=tot;k++) if(v[i][k])
for(j=1;j<=tot;j++) if(b.v[k][j])
c[i][j]=(c[i][j]+(ll)v[i][k]*b.v[k][j])%P;
return c;
}
}S,T;
ll C[10][10];
int _[10][10][5],__[10][5];
//a0 b1 c2
inline void pm(ll y)
{
while(y)
{
if(y&1) S=S*T;
T=T*T,y>>=1;
}
}
int main()
{
scanf("%d%lld%d%d",&n,&m,&p,&q);
int i,j,a,b,a1,b1,x,y;
for(i=0;i<=n;i++)
{
C[i][0]=1;
for(j=1;j<=i;j++) C[i][j]=(C[i-1][j-1]+C[i-1][j])%P;
}
if(p==1)
{
printf("1");
return 0;
}
if(p==2)
{
for(a=0;a<=n;a++) for(b=0;b<=q;b++) __[a][b]=++tot;
for(a=0;a<=n;a++) for(a1=0;a1<=a;a1++)
{
x=n-a1;
if(a1<n) for(i=0;i<=q;i++) T[__[a][i]][__[x][i]]=C[a][a1];
else for(i=0;i<q;i++) T[__[a][i]][__[x][i+1]]=C[a][a1];
}
S[1][__[n][0]]=1;
pm(m);
for(i=1;i<=tot;i++) ans=(ans+S[1][i])%P;
printf("%lld",ans);
return 0;
}
for(a=0;a<=n;a++) for(b=0;a+b<=n;b++) for(i=0;i<=q;i++) _[a][b][i]=++tot;
for(a=0;a<=n;a++) for(b=0;a+b<=n;b++)
{
for(a1=0;a1<=a;a1++) for(b1=0;b1<=b;b1++)
{
x=n-a1-b1,y=a1;
if(a1+b1<n) for(i=0;i<=q;i++) T[_[a][b][i]][_[x][y][i]]=C[a][a1]*C[b][b1]%P;
else for(i=0;i<q;i++) T[_[a][b][i]][_[x][y][i+1]]=C[a][a1]*C[b][b1]%P;
}
}
S[1][_[n][0][0]]=1;
pm(m);
for(i=1;i<=tot;i++) ans=(ans+S[1][i])%P;
printf("%lld",ans);
return 0;
}//8 1000000000000000000 3 3

【BZOJ3120】Line 矩阵乘法的更多相关文章

  1. *HDU 1757 矩阵乘法

    A Simple Math Problem Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Ot ...

  2. POJ3070 Fibonacci[矩阵乘法]

    Fibonacci Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 13677   Accepted: 9697 Descri ...

  3. 【Codeforces718C】Sasha and Array 线段树 + 矩阵乘法

    C. Sasha and Array time limit per test:5 seconds memory limit per test:256 megabytes input:standard ...

  4. 矩阵乘法的MapReduce实现

    对于任意矩阵M和N,若矩阵M的列数等于矩阵N的行数,则记M和N的乘积为P=M*N,其中mik 记做矩阵M的第i行和第k列,nkj记做矩阵N的第k行和第j列,则矩阵P中,第i行第j列的元素可表示为公式( ...

  5. hdu4920 Matrix multiplication 模3矩阵乘法

    hdu4920 Matrix multiplication Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 ...

  6. 矩阵乘法快速幂 codevs 1250 Fibonacci数列

    codevs 1250 Fibonacci数列  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond   题目描述 Description 定义:f0=f1=1 ...

  7. POJ3613 Cow Relays [矩阵乘法 floyd类似]

    Cow Relays Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7335   Accepted: 2878 Descri ...

  8. 【POJ2778】AC自动机+矩阵乘法

    DNA Sequence Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 14758 Accepted: 5716 Descrip ...

  9. 数学(矩阵乘法):HDU 4565 So Easy!

    So Easy! Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Su ...

随机推荐

  1. VB命令行参数分隔, 类似C语言中的main(int argc, char* argv[])

    VB6.0为了提供命令行参数的支持,提供了Command()接口,于是通过 Command() 函数可以得到所有传入的参数,但是很不友好的是,VB的所有参数都被合在了一起,成为了一个字符串,当有多个参 ...

  2. TCP/UDP,SOCKET,HTTP,FTP 简析

    (一)TCP/UDP,SOCKET,HTTP,FTP简析 TCP/IP是个协议组,可分为三个层次:网络层.传输层和应用层: 网络层:IP协议.ICMP协议.ARP协议.RARP协议和BOOTP协议 传 ...

  3. Java模拟公司置办货物系统(二)

    採用MVC风格,将数据写入文件,模拟公司置办货物系统.  A类表示普通员工,B类表示部门精力,C类表示採购部,D类表示资源管理部. 订单状态 1.表示申请状态 2.表示通过审批 3.表示未通过审批 4 ...

  4. 错了:用流量能够放肆,有wifi则要节制

    网络上疯传的节制体中就有这么一句:有wifi就会放肆,但用流量就会节制.榜上有名,也说明了人们对wifi网络的需求.尤其是免费wifi.从对无线网络需求方面,毫无疑问,可是从还有一角度,我则觉得是流量 ...

  5. JMeter学习笔记(四)

    1. 断言 断言组件是通过获取服务器响应数据,然后根据断言规则去匹配这些响应数据:匹配到是正常现象,此时我们看不到任何提醒,如果匹配不到,即出现了异常情况,此时JMeter就会断定这个事务失败,那么我 ...

  6. AngularJS 和 Electron 构建桌面应用

    译]使用 AngularJS 和 Electron 构建桌面应用 原文: Creating Desktop Applications With AngularJS and GitHub Electro ...

  7. Ubuntu/Debian下编译PC版的ffmpeg

    1.安装git: 在命令行下执行 sudo apt-get install git-core 2.下载最新版本的ffmpeg: git clone git://source.ffmpeg.org/ff ...

  8. JSON特殊字符的处理

    本文转自:http://blog.csdn.net/btt2013/article/details/66970735 JSon 数据中的String 传递数据时,需要处理好特殊字符. JSon数据中有 ...

  9. VBA学习笔记(1)----VBA对象属性方法

    'VBA对象 'VBA中的对象其实就是我们操作的具有方法.属性的excel中支持的对象 'Excel中的几个常用对象表示方法 '1.工作簿 ' Workbooks 代表工作簿集合,所有的工作簿,Wor ...

  10. Fast RDP Brute暴力破解3389口令

    http://www.tuicool.com/articles/b67rQfr 下载地址:https://www.rekings.com/fast-rdp-brute-gui-v2-0/