版权声明:蒻蒟的bolg... https://blog.csdn.net/Rose_max/article/details/85192562
Description
题解
很傻
就是给你 这些数 选出 个数使得他萌异或和为
如果我们知道了前 个数的异或和,显然可以知道第 个数要放什么才能让异或和为
设一个 表示选出 个数异或和为 的方案,考虑顺序,最后除一个 就可以了
转移就是
分析一下
首先先从这些数里选出 个,就是
然后这样的话 后面会有空集或者和前面相同的
是空集的话前面显然是
和前面相同的话,有 地方可以相同
去除之后有 个数,这时候他萌的异或和是0
然后这两个相同的数一共有 种选法
就是
就没了…
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
#include<ctime>
#include<map>
#include<bitset>
#define LL long long
#define mp(x,y) make_pair(x,y)
#define pll pair<long long,long long>
#define pii pair<int,int>
using namespace std;
inline int read()
{
int f=1,x=0;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int stack[20];
inline void write(int x)
{
if(x<0){putchar('-');x=-x;}
if(!x){putchar('0');return;}
int top=0;
while(x)stack[++top]=x%10,x/=10;
while(top)putchar(stack[top--]+'0');
}
inline void pr1(int x){write(x);putchar(' ');}
inline void pr2(int x){write(x);putchar('\n');}
const int MAXN=1000005;
const LL mod=1e8+7;
int n,m;
LL f[MAXN];
LL pow_mod(LL a,LL b)
{
LL ret=1;
while(b)
{
if(b&1)ret=ret*a%mod;
a=a*a%mod;b>>=1;
}
return ret;
}
int main()
{
n=read();m=read();
f[0]=1;
LL u1=(pow_mod(2,n)-1+mod)%mod,u2=u1,temp=1;
for(int i=2;i<=m;i++)
{
temp=temp*(u2--)%mod;if(u2<0)u2+=mod;
f[i]=((temp-f[i-1]+mod)%mod-f[i-2]*(i-1)%mod*(u1-(i-2)+mod)%mod+mod)%mod;
}
temp=1;
for(int i=1;i<=m;i++)temp=temp*i%mod;
temp=pow_mod(temp,mod-2);
pr2(f[m]*temp%mod);
return 0;
}