[51nod] 1301 集合异或和
生活随笔
收集整理的這篇文章主要介紹了
[51nod] 1301 集合异或和
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
考慮不限制xor{Y}>xor{X}
- 考慮n=m的情況,每個數i∈[1,n]可以被分配到X集合或Y集合,或不分配
- 設f[S]表示{X} xor {Y} == S的方案數
- 有f[S]+=2*f[S^i]
- 考慮n!=m,那就是多余的部分得強制分配,分開兩個轉移即可
考慮限制xor{Y}>xor{X}
- 對于數B>A,在二進制表示下,就是B和A的前面相等,直到某一位B為1,A為0,之后無所謂
- 枚舉這一位k,限制B(xor{Y})第k位為1,且B xor A第k位為0(統計答案限制范圍)
- 狀態加一維f[S][0/1]表示A xor B==S且B的第k位是0/1
- 轉移分開討論兩個情況
- 1.放進X集合,直接繼承狀態
- 2.放進Y集合,根據i第k位轉移 #include<iostream>
#include<cstring>
#include<cstdio>using namespace std;inline int rd(){int ret=0,f=1;char c;while(c=getchar(),!isdigit(c))f=c=='-'?-1:1;while(isdigit(c))ret=ret*10+c-'0',c=getchar();return ret*f;
}const int MOD = 1000000007;
const int MAXN = 4096;
int n,m;long long f[MAXN][2],g[MAXN][2];
long long ans;int main(){n=rd();m=rd();int mx=max(n,m),tmp=mx;int len=0;while(tmp){len++;tmp>>=1;}for(int k=1;k<=len;k++){memset(f,0,sizeof(f));f[0][0]=1;for(int i=1;i<=mx;i++){memcpy(g,f,sizeof(f));for(int s=mx<<1;s>=0;s--){if(i<=n){f[s][0]+=g[s^i][0];f[s][1]+=g[s^i][1];}if(i<=m){f[s][0]+=g[s^i][(i>>(k-1))&1];f[s][1]+=g[s^i][((i>>(k-1))+1)&1];}f[s][0]%=MOD;f[s][1]%=MOD;}}for(int i=(1<<(k-1));i<(1<<k);i++){ans+=f[i][1];}ans%=MOD;}cout<<ans;return 0;
}
?
轉載于:https://www.cnblogs.com/ghostcai/p/9606214.html
總結
以上是生活随笔為你收集整理的[51nod] 1301 集合异或和的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何在java中使用retainAll取
- 下一篇: PHP cosh() 函数