题解:P15569 [COCI 2025/2026 #5] 结构 / Struktura
首先,每个数都独立地、等概率地从
然后我们考虑怎么算出满足条件的
在满足
我们设定一个 DP 数组
- 从大到小第一个(即
a_1 的n+1 、a_2 的n 等) 被选了,记为4 。 - 从大到小第二个(即
a_1 的n 、a_2 的n-1 等) 被选了,记为2 。 - 从大到小第三个(即
a_1 的n-1 、a_2 的n-2 等) 被选了,记为1 。
最后的
最后写出 DP 转移方程
经过思考可以发现,记录上述的第一条是无用的,即
然后可以发现,符合所有条件有效的
最后推出:
然后把
记得特判
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int mod=1e9+7;
int ksm(int A,int B)
{
int S=1;
while(B)
{
if(B&1)S=S*A%mod;
A=A*A%mod;
B>>=1;
}
return S;
}
struct jz//2*2
{
int c[3][3];
};
jz operator * (jz A,jz B)
{
jz T;
T.c[1][1]=0,T.c[1][2]=0;
T.c[2][1]=0,T.c[2][2]=0;
for(int i=1;i<=2;i++)
for(int j=1;j<=2;j++)
for(int l=1;l<=2;l++)T.c[i][l]=(T.c[i][l]+A.c[i][j]*B.c[j][l]%mod)%mod;
return T;
}
jz jzksm(jz A,int B)
{
jz S;
S.c[1][1]=1,S.c[1][2]=0;
S.c[2][1]=0,S.c[2][2]=1;
while(B)
{
if(B&1)S=S*A;
A=A*A;
B>>=1;
}
return S;
}
int n,k,c[100005];
signed main()
{
cin>>n>>k;
if(k<n)
{
cout<<0;
return 0;
}
jz A;
A.c[1][1]=1,A.c[1][2]=1;
A.c[2][1]=0,A.c[2][2]=0;
jz B;
B.c[1][1]=1,B.c[1][2]=1;
B.c[2][1]=1,B.c[2][2]=0;
jz P=(A*jzksm(B,n-1));
cout<<P.c[1][1]*ksm(ksm(k,mod-2),n)%mod;
return 0;
}
::::