

状压dp+矩阵转移,据说正解是dfs出的合法状态,,但难道不是三个for就行了吗2333
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#define ll long long
const int ha=1000000007;
using namespace std;
int C[12][12],n,P,Q,cnt;
struct node{
int a[3],full;
}zt[233];
inline int add(int x,int y){
x+=y;
return x>=ha?x-ha:x;
}
struct matrix{
int a[199][199];
inline void clear(){
memset(a,0,sizeof(a));
}
matrix operator *(const matrix &u)const{
matrix r;
r.clear();
for(int k=1;k<=cnt;k++)
for(int i=1;i<=cnt;i++)
for(int j=1;j<=cnt;j++) r.a[i][j]=add(r.a[i][j],a[i][k]*(ll)u.a[k][j]%ha);
return r;
}
}base,ANS;
inline void init(){
C[0][0]=1;
for(int i=1;i<=8;i++){
C[i][0]=1;
for(int j=1;j<=i;j++) C[i][j]=add(C[i-1][j-1],C[i-1][j]);
}
}
inline void can(int i,int j){
node x=zt[i],y=zt[j];
if(y.a[1]<=x.a[0]&&y.a[2]<=x.a[1]&&x.full+(y.a[1]+y.a[2]==n?1:0)==y.full){
base.a[i][j]=C[x.a[0]][y.a[1]]*(ll)C[x.a[1]][y.a[2]]%ha;
}
}
inline void build(){
for(int i=n;i>=0;i--)
for(int j=(P==2?0:n-i);j>=0;j--)
for(int l=0;l<=Q;l++) zt[++cnt]=(node){i,n-i-j,j,l};
base.clear();
for(int i=1;i<=cnt;i++)
for(int j=1;j<=cnt;j++) can(i,j);
}
inline void solve(ll y){
ANS.clear();
for(int i=1;i<=cnt;i++) ANS.a[i][i]=1;
int ans=0;
for(;y;y>>=1,base=base*base) if(y&1) ANS=ANS*base;
/*
for(int i=1;i<=cnt;i++){
for(int j=1;j<=cnt;j++) printf("%d ",ANS.a[i][j]);
puts("");
}
*/
for(int i=1;i<=cnt;i++) ans=add(ans,ANS.a[1][i]);
printf("%d
",ans);
}
int main(){
// freopen("line.in","r",stdin);
// freopen("line.out","w",stdout);
init();
ll m;
scanf("%d%lld%d%d",&n,&m,&P,&Q);
if(P==1){
puts("1");
return 0;
}
build();
solve(m);
return 0;
}