BZOJ 4762 最小集合

2021-07-30 08:40:01 字數 2187 閱讀 6447

定義乙個非空集合是合法的,當且僅當它滿足以下兩個條件。

1、集合內所有元素and和為0

2、它的非空子集中僅有它本身滿足1

給出乙個集合s,求它的合法非空子集數。

第一行乙個正整數n,表示|s|

第二行n個非負整數ai,表示集合內的元素。

n≤1000,ai<1024

乙個整數,表示s的合法非空子集數。答案可能很大,請mod 1e9+7之後輸出。

1 2 4 4

樣例解釋:滿足條件的集合為,,,,

**棟爺的部落格

先把給定集合所有數取反。

比如有效位數是4位,1101就變成0010。

那麼問題變成,所有元素or和為1023,而去掉任意乙個元素後or和均不為1023。

那麼接下來我們來設乙個詭異的狀態。

因為要知道去掉乙個人元素會不會使or和為1023,因此我們前後都要知道。

可以設乙個f[i,j,k]表示做完了i個數,前面選擇的一些數or和為j,我們希望後面選出的數or和為k。

然而隨便推一推都覺得不會轉移啊。。

這時趕緊改一下狀態,設f[i,j,k]表示做完了i個數,前面選擇的一些數or和為j,我們希望後面選出的數or和包含k(什麼叫包含?x包含k需滿足x&k=k)

設第i+1個數為x。

不選?

f[i+1][j][k]+=f[i][j][k]

選呢?

假設後面部分不包含x時是k』。

我們發現k』需要滿足兩個條件:

1、k』|x=k(根據狀態定義)

2、k』|j|x!=k』|j(如果等了那麼就能去掉x了)

滿足條件的k』肯定存在一些包含關係,而我麼的狀態設的也是包含,所以轉移會比較方便。

先只考慮滿足第乙個條件:

f[i+1][j|x][k^(k&x)]+=f[i][j][k]

這個很容易考慮,如果k的某一位有1,x該位也有1,那麼k』的這一位可以是0也可以為1。

再去掉滿足第乙個條件而不滿足第二個條件的:

f[i+1][j|x][(k^(k&x))|(x^(x&j))]-=f[i][j][k]

這是個什麼意思?先看後面,顯然只有x的某一位是1,而j的對應位是0時才有1的貢獻,意思就是x會給j的哪些原本沒有1的位變成1。

而如果k』的這些位也有1,那麼j|k』後,再或x將不變,因此會不滿足第二個條件。

然後這個dp就是正確的,初始f[0][0][0]=1,最後答案是f[n][1023][0]。

假設有m位,這樣做是n∗4^m

考慮優化吧。我們來證明,如果f[i][j][k]不為0,一定有j包含k。

初始時顯然滿足。

看第一條轉移,f[i+1][j|x][k^(k&x)]+=f[i][j][k]。

假如j包含k,k的某位為0時,k&x的對應位肯定也是0,所以k^(k&x)並不會多1,反而可能少1,但j|x不會少1,因此有j|x包含k^(k&x)。

看第二條轉移,f[i+1][j|x][(k^(k&x))|(x^(x&j))]-=f[i][j][k]。

假如j包含k,記k』=k^(k&x)。假如k』某位為1,可以不管它,由上面的結論j|x的這位也會是1。假如k某位為0,k』這位也是0,而x^(x&j)是1,那麼最終這位會是1,而因為x^(x&j)的這位是1,x這位必須是1,那麼j|x這位也有1了。

這樣列舉j後每次只需列舉乙個j包含的k,有個快捷的列舉方法見**。

那麼可以證明複雜度降為

n∗3^m

#include 

#define n 1030

#define mod 1000000007

using

namespace

std;

int n;

int f[2][n][n], tmp;

void add(int &t, int d)

int main()

for (int j = 0; j < 1024; ++ j)

add(f[tmp][0][j], f[!tmp][0][j]);

add(f[tmp][0][j & d], f[!tmp][0][j]);

add(f[tmp][0][j & (0 | d)], mod - f[!tmp][0][j]);}}

printf("%d", f[tmp][0][0]);

}

EXT 最小集合

想把ext放入自己的專案,需要自己整理一下,因為發布包裡的東西並非都是必要的,比如文件,比如例子,比如源 必要的最小集合是這樣 ext all.js,adapter ext ext base.js,build locale ext lang zh cn.js和整個resources目錄。ext al...

51nod 最小集合

最小集合 system message 命題人 基準時間限制 1 秒 空間限制 131072 kb 分值 80 a君有乙個集合。這個集合有個神奇的性質。若x,y屬於該集合,那麼x與y的最大公因數也屬於該集合。但是他忘了這個集合中原先有哪些數字。不過幸運的是,他記起了其中n個數字。當然,或許會因為過度...

51nod 1616 最小集合

原題鏈結 1616 最小集合 基準時間限制 1 秒 空間限制 131072 kb 分值 80 難度 5級演算法題 a君有乙個集合。這個集合有個神奇的性質。若x,y屬於該集合,那麼x與y的最大公因數也屬於該集合。但是他忘了這個集合中原先有哪些數字。不過幸運的是,他記起了其中n個數字。當然,或許會因為過...