CDOJ 1294 天行廖的遊戲 dp 容斥

2021-09-09 01:42:36 字數 1944 閱讀 3712

天行廖的遊戲

一日在喵哈哈村,天行廖和沈寶寶正在玩乙個遊戲。

天行廖分別在\(n\)個紙片上寫上乙個數字,並放到乙個盒子中。

現在沈寶寶要從盒子中抓出任意張紙片。

如果沈寶寶抓出的紙片上的數字\(a\_\),\(a\_\),....\(a\_\)滿足\(a\_\) & \(a\_\) & ....\(a\_\)$ = 0$ ( \(i\_ < i\_ … < i\_\)),那麼天行廖贏得這次遊戲的勝利,否則沈寶寶贏。

第一行輸入\(1\)個整數\(n。\)(\(1 \leq n \leq 10^6\))

第二行輸入\(n\)個整數\(a\_1,a\_2....a\_n\)。($1 \leq a_i \leq 10^6 $)

輸出獲勝的方案數量。因為結果可能很大,輸出答案對\(10^9+7\)取模的結果即可。

65 2 0 5 2 1

首先,我們再看一遍題意:對於乙個長度為n的數列a1,a2...an,挑出任意個數,使得這些數的且運算結果為0。

首先暴力2^n列舉是肯定不行的。考慮不那麼暴力的dp做法,令dp[i][j]表示從前i個數選結果為j的方案有多少種,轉移方程為dp[i][j] = sigma(dp[i - 1][k]) (k & a[i] = j),複雜度為n^3,顯然也不行...

於是我們考慮是否能用容斥原理做。1e6的二進位制表示式有20位,總方案數為2^n,然後我們減去結果第一位為1的方案數,第二位為2的方案數...第二十位為1的方案數,即某一位為1的方案數。然後根據容斥原理,我們再加上結果某兩位為1的方案數,減去結果某三位為1的方案數...,加上全為1的方案數。假設f(i)為結果為i的方案數量(令f(0) = 2 ^ n),g(i)為i二進位制下1的個數,則ans = sigma(f(i)*(-1)^(g(i)))。

那麼現在問題即如何計算f(i)。若要使得k個數b1,b2...,bk的且運算為i,那麼對於所有i為1的位,任意bj在該位置上也都為1,即bj & i = i。如果我們能算出滿足aj & i = i的數的個數cnt(i),就能得到f(i) = 2 ^ cnt(i),於是問題轉換為如何快速計算cnt(i)。

我們令cnt[k][i]表示只有前k位與i不同且滿足aj & i = i的數的個數,邊界cnt[0][i]表示正好為i的數的個數。現在分兩種情況討論cnt[k][i]的遞推式:

1、i的第k位是1,那麼cnt[k][i] = cnt[k - 1][i],因為若第k位不同,則與i作且運算是第k位為0,所以相當於只有前k-1位不同。

2、i的第k位是0,則是第k位0或1沒有影響,對比第一種情況需要加上前k-1位不同且第k位為1的數的個數。顯然這個方案數等於dp[k - 1][i + 2^k],則得到遞推式cnt[k][i] = cnt[k - 1][i] + cnt[k - 1][i + 2 ^ k]。

因為位數k最大為log(1e6)約等於20,於是我們就能在o(nk)(k=20)的複雜度計算出cnt(i),並在o(n)的時間內完成容斥的計算,總時間複雜度為o(nk)。至此,我們解完了這題。

#include using namespace std;

typedef long long ll;

const int n = 1 << 20;

const ll mod = 1e9 + 7;

int n,m;

ll dp[21][n];

///dp[i][x]表示,二進位制下只有前i位可能與x不同的數與x進行and運算仍然為x的數的個數

ll g[n];

bool s[n];

void init()

}void work()

ll ans = 0;

for(int i = 0;i < n;i++)

ans = ( ans + (s[i]?(-1ll):1ll) * g[dp[20][i]] + mod ) % mod;

printf("%lld\n",ans);

}int main()

訓練總結 1 29

今天看ac自動機,看得迷迷糊糊,看起來就是字典樹 kmp。字典樹還好說,當時kmp有點沒看懂,又看了一下,這次kmp倒是懂了,ac自動機還是有點沒看懂。照著部落格上的模板試著敲了一遍。構造next陣列那裡還是有點看不懂。還得繼續看。includeusing namespace std const i...

原創 1 29總結

下圖就是乙個html的乙個簡單例項 宣告有助於瀏覽器中正確顯示網頁 宣告不區分大小寫,圖為html 5 宣告 html 元素是 html 頁面的根元素 head 元素包含了文件的元 meta 資料,如 meta charset utf 8 定義網頁編碼格式為 utf 8。title 元素描述了文件的...

12 9每日部落格

首先給資料集名稱那一列 新增點選事件 然後呼叫乙個js方法,這個方法中包含layui元件中的彈出視窗的方法 function showthisdatatab name,size 然後我的思路是將這個資料集的名稱或者id傳遞給要開啟的那個html網頁,在那個網頁中在呼叫乙個資料 請求後台並得到資料庫的...