不能不计算重复情况,用容斥原理
避免了二维容斥
部分分:
m=1 ans=1;
m=2 ans=3^n-2; 每一行有三种情况,第一个是黑,第二个是黑,两个全是黑,减去一行全是白一行全是黑的两种情况...
n,m<=5 搜索;
n,m<=6 打表;
#include<iostream> #include<cstdio> using namespace std; typedef long long ll; const ll mod=1e9+7; const ll maxn=1e5+7; ll n,m; ll fac[200005],ifac[200005]; ll qpow(ll a,ll b,ll p){ ll ans=1; for(;b;b>>=1,a=(a*a)%p){ if(b&1) {ans*=a;ans%=mod;} } return ans; } void get(){ fac[0]=1; for(int i=1;i<=200000;i++){ fac[i]=(fac[i-1]*i)%mod; } ifac[200000]=qpow(fac[200000],mod-2,mod); for(int i=200000;i>=1;i--){ ifac[i-1]=(ifac[i]*i)%mod; }//计算逆元 } ll C(int m,int n){ return fac[n]*ifac[m]%mod*ifac[n-m]%mod; } int main(){ cin>>n>>m;get(); ll ans=0; for(ll k=0;k<=n;k++){ ll c=fac[n]*ifac[k]%mod*ifac[n-k]%mod; ll p=(qpow(2,n-k,mod)%mod-1+mod)%mod; if(k%2==1){ ans=(ans-c*qpow(p,m,mod)+mod)%mod;ans%=mod; } if(k%2==0){ ans=ans+c*qpow(p,m,mod)%mod;ans%=mod;ans%=mod; } ans%=mod; } cout<<ans<<endl; return 0; }
要注意的是,不要用if(!i&1)