51Nod 1301 集合异或和 —— 异或DP
题目:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1301
参考博客:https://blog.csdn.net/qq_33229466/article/details/78418414
原来是DP。
代码如下:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; typedef long long ll; int const maxn=2005,mod=1e9+7; int n,m,w,bin[15]; ll ans,f[3][2050][15]; int get(int x){int ret=0; while(x)ret++,x>>=1; return ret;} void init() { bin[0]=1; for(int i=1;i<15;i++)bin[i]=(bin[i-1]<<1); } int main() { init(); scanf("%d%d",&n,&m); w=get(max(n,m)); for(int i=0,p,q;i<=w;i++) { memset(f,0,sizeof f); p=0; f[0][0][0]=1; int lim=0; for(int j=1;j<=max(n,m);j++)//枚举数 { p^=1; q=!p; if(j>=bin[lim])lim++; // int tmp=(j&bin[i]); //j&bin[i]不仅是0或1!!! bool tmp=(j&bin[i]); for(int s=0;s<bin[lim];s++)//< { f[p][s][0]=f[q][s][0]; f[p][s][1]=f[q][s][1]; for(int k=0;k<=1;k++) { if(j<=m)(f[p][s][k]+=f[q][s^j][k^tmp])%=mod;//给B if(j<=n)(f[p][s][k]+=f[q][s^j][k])%=mod;//给A } } } for(int s=bin[i];s<bin[i+1];s++)ans=(ans+f[p][s][1])%mod; } printf("%lld\n",ans); return 0; }