A- A Bit Common
这题感觉只需要考虑一下如何去重即可。
我们可以枚举非空子序列的大小,为了防止重复,我们就需要考虑如何能使长度为i的非空子序列唯一合法。很明显的一点是当当前子序列合法时,任何一个2进制最低位为1的数加入到当前子序列中,序列的与值仍然为1。也就是说,假设当前长度为i的子序列合法,那么剩下的n-i个数的二进制位最低位都必须是0,否则假设n-i个数里有1个数二进制最低位为1,那么我们就会多算长度为i+1时的贡献。
那么答案就很明显了,从n个位置选择i个位置,每个二进制位有0和1两种填法,为了使枚举的i个数合法,那么除了最低位全1,其他每一位i个数都不能全选1,共m-1位,则有,剩下n-i个数最低位一定是零,剩下m-1位随意则有
答案则为
注意到模数可能是合数,不能使用逆元,因此可以使用递推求组合数,赛时忘记了这个做法,我用的是质因数分解计算的组合数。
#include<bits/stdc++.h>
#define lowbit(x) (x&(-x))
#define rep(x,a,b) for(int x=a;x<=b;x++)
#define pre(x,a,b) for(int x=a;x>=b;x--)
#define ac puts("Yes")
#define wa puts("No")
#define ll long long
#define int long long
#define endl "\n"
#define pb push_back
#define pii pair<ll, ll>
#define de cout<<1;
#define mem(a,x) memset(a,x,sizeof a)
#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define ull unsigned long long
#define eps 1e-6
#define RI register int
#define CI const int&
using namespace std;
const int N = 1e6 + 20;
int n, m, k, mod1;
int st[N] = {1, 1};
ll phi[N], idx;
ll c[N];
void su()
{
rep(i, 2, 1000000)
{
if(!st[i]) phi[++idx] = i;
rep(j, 1, idx)
{
if(phi[j] * i > 1000000) break;
st[i * phi[j]] = 1;
if(i % phi[j] == 0) break;
}
}
}
ll qmi(ll a, ll b)
{
ll base = 1;
while(b)
{
if(b & 1) base = base * a % mod1;
b >>= 1;
a = a * a % mod1;
}
return base;
}
void jc()
{
map<int, int>mp;
int now = n;
c[0] = 1;
c[n] = 1;
rep(i, 1, n / 2)
{
int nn = now;
for(int j = 1; j <= idx && phi[j] * phi[j] <= nn; j ++ )
{
int cnt = 0;
while(nn % phi[j] == 0) cnt ++ , nn /= phi[j];
if(cnt) mp[phi[j]] += cnt;
}
if(nn > 1) mp[nn] ++ ;
nn = i;
for(int j = 1; j <= idx && phi[j] * phi[j] <= nn; j ++ )
{
int cnt = 0;
while(nn % phi[j] == 0) cnt ++ , nn /= phi[j];
if(cnt) mp[phi[j]] -= cnt;
}
if(nn > 1) mp[nn] -- ;
now -- ;
ll res = 1;
for(auto it : mp)
{
res = (res * qmi(it.first, it.second) % mod1) % mod1;
}
c[i] = res;
c[n - i] = res;
}
}
void solve()
{
cin >> n >> m >> mod1;
jc();
ll ans = 0;
rep(i, 1, n)
{
ll res = 0;
res = ((c[i] % mod1 * qmi(((qmi(2, i) - 1ll + mod1) % mod1), m - 1) % mod1) % mod1 * qmi(qmi(2, n - i), m - 1) % mod1) % mod1;
ans = (ans + res) % mod1;
}
cout << ans;
}
signed main()
{
IOS;
int t;
t = 1;
su();
// cin >> t;
while(t -- )
{
solve();
}
return 0;
}