51nod1301 集合異或和

2021-07-25 04:58:52 字數 1416 閱讀 8078

已知兩個整數n與m,你需要構造兩個整數集合x與y,且需要滿足以下要求:

(1)對所有的xi∈x,滿足1<=xi<=n;對所有的yj∈y,滿足1<=yj<=m; (x與y可以為空集)

(2)x∩y=φ;(但不要求集合x與y的元素個數,只要兩者沒有交集即可)

不妨設構造後的集合x含有n個元素,而集合y有m個元素,令 a=x1 xor x2 xor x3 xor … xor xn, b=y1 xor y2 xor y3 … xor ym。其中,xor 為異或運算,並且 稱a與b分別是集合x與集合y的異或和。如果乙個集合為空集,那它的異或和被認為是0。

求對於給定的n與m符合要求(1)、(2)且滿足

a<

b 的集合x、y的不同構造方法個數,輸出結果 mod 10^9 + 7。其中,兩種構造方案被認為是不同的,當且僅當兩種方案中的集合x或集合y包含的元素集不完全相同。

例如:n=2,m=2,則符合條件的x與y有如下四組:

x={} and y=

x={} and y=

x={} and y=

x= and y=

列舉a xor b的第乙個非0位x。

那麼顯然b的第x位為1,a的第x位為0,就可以滿足

a設f[i,j,0~1]表示分配完了前i個數,目前異或值為j,b的第x位是0或1的方案數。

轉移就是看第i+1個數給a還是b。

統計答案的時候,顯然為了滿足異或和最高位為x,我們要找所有在[2^x,2^(x+1)-1]範圍的i,加上f[max(n,m),i,1](b的第x位必須為1)

複雜度為2次方帶log,有點卡。

卡常數就用模優化,只有當值》=模數是再用減法去減,詳見**。

#include#include#include#define fo(i,a,b) for(i=a;i<=b;i++)

using namespace std;

const

int maxn=2000+10,mo=1000000007;

int f[2][maxn*2][2];

int i,j,k,l,t,n,m,mx,ans,x,zjy,now;

int main()

if (i<=m)

f[now][j][0]=(f[now][j][0]+f[1-now][j][0]);

f[now][j][1]=(f[now][j][1]+f[1-now][j][1]);

if (f[now][j][0]>=mo) f[now][j][0]-=mo;

if (f[now][j][1]>=mo) f[now][j][1]-=mo;}}

fo(i,(1

<1

<2-1) ans=(ans+f[now][i][1])%mo;

}printf("%d\n",ans);

}

51nod 1301 集合異或和

已知兩個整數n與m,你需要構造兩個整數集合x與y,且需要滿足以下要求 1 對所有的xi x,滿足1 xi n 對所有的yj y,滿足1 yj m x與y可以為空集 2 x y 但不要求集合x與y的元素個數,只要兩者沒有交集即可 不妨設構造後的集合x含有n個元素,而集合y有m個元素,令 a x1 xo...

51nod 1301 集合異或和(DP)

因為當 a時,會存在在二進位制下的一位,滿足這一位b的這一位是 1 a 的這一位是 0 我們列舉最大的這一位。設為 x 吧。設計狀態。dp i j 1 0 代表考慮了前i個數,異或和為j的情況下 b 的第 x 位為 1 或 0 有多少種情況。然後隨便轉移一下,再隨便統計答案一下就好了。如果不知道如何...

51nod 1577 異或湊數

從左到右一共n個數,數字下標從1到n編號。一共m次詢問,每次詢問是否能從第l個到第r個數中 包括第l個和第r個數 選出一些數使得他們異或為k。資料量比較大。輸入請用掛 1 23 4 5 6 7 8 intread 輸出請用puts input 單組測試資料。第一行乙個整數n 0output m行,每...