题目
题意:
Constructed an array
b
b
b of length
n
−
1
n−1
n−1, where
b
i
=
m
i
n
(
a
i
,
a
i
+
1
)
b_i=min(a_i,a_{i+1})
bi=min(ai,ai+1).
Constructed an array
c
c
c of length
n
−
1
n−1
n−1, where
c
i
=
m
a
x
(
a
i
,
a
i
+
1
)
c_i=max(a_i,a_{i+1})
ci=max(ai,ai+1).
Constructed an array
b
′
b^′
b′ of length
n
−
1
n−1
n−1, where
b
i
′
=
b
p
i
b^′_i=b_{p_i}
bi′=bpi.
Constructed an array
c
′
c^′
c′ of length
n
−
1
n−1
n−1, where
c
i
′
=
c
p
i
c^′_i=c_{p_i}
ci′=cpi.
知
b
′
,
c
′
b^′,c^′
b′,c′求
a
a
a
发现
b
i
′
,
c
i
′
b_i^′,c_i^′
bi′,ci′一定是连续两个a,一个是左边的,一个是右边的。
那么就把这两个数连上一条边,求一条欧拉路(经过所有边的路)
那么我们把欧拉路的顶点序列拿来当作
a
1
.
.
.
.
a
n
a_1....a_n
a1....an发现刚好满足。。。。。。
注意欧拉回路需要当前弧优化???
AC Code:
#include<bits/stdc++.h>
#define maxn 250
#define mod 1000000007
using namespace std;
int n,k,m;
int S,M;
int bit[maxn];
struct mat{
int a[maxn][maxn];
mat (int d=0){memset(a,0,sizeof a);for(int i=0;i<maxn;i++) a[i][i]=d;}
mat operator *(const mat &B)const{
mat ret = mat(0);
for(int i=0;i<S;i++)
for(int j=0;j<S;j++) if(a[i][j])
for(int k=0;k<S;k++) if(B.a[j][k])
ret.a[i][k] = (ret.a[i][k]+ a[i][j] * 1ll * B.a[j][k])%mod;
return ret;
}
}A;
mat Pow(mat base,int k){
mat ret = mat(1);
for(;k;k>>=1,base=base*base)
if(k&1)
ret=ret*base;
return ret;
}
int main(){
scanf("%d%d%d",&n,&k,&m);
M = 1<<m;
S = (k+1) * M;
for(int sta=1;sta<M;sta++)
bit[sta] = bit[sta-(sta&-sta)] + 1;
for(int sta=0;sta<M;sta++)
for(int i=0;i<=k;i++){
A.a[i*M+sta][i*M+((sta<<1)&(M-1))]++;
if(i<k)A.a[i*M+sta][(i+1)*M+((sta<<1)&(M-1))+1]+=bit[sta]+1;
}
A = Pow(A,n);
int ans = 0;
for(int sta=0;sta<M;sta++){
ans = (ans + A.a[0][k*M+sta])%mod;
}
printf("%d\n",(ans+mod)%mod);
}