A | A Bit Common |
#include<bits/stdc++.h>
using namespace std;
//const int mod=998244353;
int dx[4]={0,0,-1,1};
int dy[4]={-1,1,0,0};
#define int long long
typedef pair<int,int> pii;
const int N=5010;
int a[N];
int n,m,q;
int c[N][N];
void fun()
{
for(int i=0;i<=n;i++)
{
for(int j=0;j<=i;j++)
{
if(j==0)c[i][j]=1;
else c[i][j]=(c[i-1][j]+c[i-1][j-1])%q;
}
}
}
int qmi(int a,int b,int q)
{
int res=1;
while(b)
{
if(b&1)res=(res*a)%q;
b>>=1;
a=(a*a)%q;
}
return res;
}
void solve()
{
cin>>n>>m>>q;
fun();
for(int i=1;i<=n;i++)
{
int t=(qmi(2,i,q)-1)%q;//2^i-1种情况
a[i]=qmi(t,m-1,q)%q;//m-1位
}
int ans=0;
for(int i=1;i<=n;i++)
{
int t=qmi(2,n-i,q)%q;
int x=qmi(t,m-1,q)%q;
ans=(ans+(c[n][i]*x)%q*a[i]%q)%q;
}
cout<<ans%q<<endl;
}
signed main()
{
int good_luck_to_you;
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
good_luck_to_you=1;
//cin>>good_luck_to_you;
while(good_luck_to_you--)
{
solve();
}
system("pause");
}
本题的大致意思是 存在长度为n的A序列,且A中的数的范围为0-2^m-1,存在子序列的与运算结果为1,有多少个这样的A。
思路:考虑子序列,如果让&结果为1,那么我们必须选第0位为1的数,即奇数,有2^i-1(i为奇数个数),那么m-1位则是(2^i-1)^(m-1),剩下的n-i位位偶数,则有(n-i)^(m-1),最后因为是子序列,所以要选出i个数为奇数,用到组合数的思想,最后的答案为C[n][i]*(2^i-1)^(m-1)*(n-i)^(m-1)。
总结:本题其实我们一开始的思路偏了,对于这么多位数的数,我们就应该从每一位开始考虑,然后当时思路偏了最后发现方案数也重复了不少,最后把子序列和子串都给搞混了,经过这次比赛,最好的办法是自己想出来的自己写,还是要静下心来写一道题,不要被别人的话语给吓到,他认为你不可能,你偏要做给他看,希望我们的每一次训练都是有效的。