题意
输入一个n和m,要求从0道2^m-1中取出n个数进行逐个异或,求出最后的异或值不为0 的情况数,并且任意一个子区间的异或值也不能为0。可以取重复的数。
思路
列举:任何情况下,0做一个子区间,一定会出现0的情况,所以任何时候都不选0;
n=1时,
不能为0,所以有2^m-1中情况;
n=2时,
第一位有2^m-1种情况,
第二位和第一位不相等, 第二位2^m-2种情况;
n=3时,
第一位有2^m-1种情况,
第二位和第一位不相等, 第二位2^m-2种情况,
第三位与第二位不相等,且不等于第二位和第一位的异或,所以有2^m-3种情况;
……
以此类推
AC代码
#include<bits/stdc++.h>
using namespace std;
long long n,m,s,mul;
long long qmi(long long m,long long k,long long q)
{
//快速幂模板。
long long ans=1%q,t=m;;
while(k)
{
if(k&1)
ans=ans*t%q;
t=t*t%q;
k>>=1;
}
return ans;
}
int main()
{
cin>>n>>m;
s=qmi(2,m,1000000009)-1;
//cout<<s<<endl;
mul=1;
for(int i=1;i<=n;i++)
{
mul=mul*(s-i+1)%1000000009;//每次都要取模避免溢出
}
cout<<mul<<endl;
return 0;
}