CF1119H Triple 西行寺無餘涅槃

2022-09-21 20:48:13 字數 2479 閱讀 3316

現在有 \(n\) 個物品,同時有 \(k\) 種屬性,每個屬性有其價值 \(w_i\)

每個物品的一種屬性對應乙個權值 \(a_\in[0,2^m)\)

現在對於 \([0,2^m)\) 中的每個 \(x\) 求出

\[\sum\limits_}\left[\oplus_^n a_=x\right]\prod_^n w_

\]\(n\le 10^5,m\le 16,m+k\le 20\)

「fwt 變換矩陣是滿秩的」

一種樸素的做法是求出每物品的每個屬性所形成的集合冪級數暴力 \(\rm fwt\) 並將點值乘起來再還原

看起來還原的一步是不可少的,那麼嘗試加速求點值的部分

直接求得的 \([x^i]\rm fwt_\) 的項數達到了 \(\theta(n2^m)\) 級別,那麼嘗試對其分類,最直接的方式就是使用 \(\pm1\) 來表示點值係數的正負

更具體地,如果乙個 \(i\) 的 \(\rm\left(\sum_^k x^}\right)\) 中係數表示法下的 \(k\) 個位置向點值表示法下的第 \(i\) 位貢獻為 \(ctr_i\dots ctr_k\left(\forall \ i\in [1,k]\ ctr_i\in \\right)\),使用乙個長度為 \(k\) 的二進位制數字表示 \(ctr\) 陣列,其中 \(ctr_i=-1\) 的位讓 \(x\) 的第 \(i\) 為是 \(1\)

嘗試對 \([0,2^m)\) 中的每個 \(i\) 維護長度為 \(2^k\) 的陣列 \(cnt_i\),其中 \(cnt_\) 表示對點值表示法下位置 \(i\) 貢獻狀態為 \(j\) 的物品的數量

那麼如果求出了 \(2^\times 2^k\) 個 \(cnt_\),容易得到每個狀態的 \(w_i\) 對該點值處的貢獻和,快速冪再乘積即可得到正確點值

問題轉化為了求所有的 \(cnt_\),一種常用的手段是找等量關係來解方程,為了簡化問題,下面的討論都只考慮對 \(\rm [x^q]fwt(ans)\) 處的 \(cnt\) 來展開

嘗試取出 \(\\) 的乙個子集 \(t\),設 \(b_i=\oplus_^k a_\),寫出其集合冪級數 \(\sum\limits_^n }\left(x^b_i\right)=}\left(\sum\limits_^n x^\right)\)

這裡的和式變換是因為 \(\rm fwt\) 的過程中係數是統一的,也就是說\(\rm fwt\) 是線性變換,類似於可以使用一次函式進行 \(\rm lagrange\) 插值

我們考察 \([x^q]}\left(\sum\limits_^n x^\right)\) 和 \([x^t]}\left(\sum\limits_^ cnt_x^i\right)\),先看左邊:

注意到 \(\oplus_^n (a_i\&q)= \left(\left(\oplus_^n a_i\right)\&q\right)\)

如果你不會證明

這個等量關係在 \(a_i,q\ge 1\) 的時候按二進位制位拆開考慮即可,因為位之間獨立,\(n=2\) 時討論是 \(\exist q=a_i\) 與否即可

在 \(n>2\) 的時候可以令 \(a'_1=a_1\oplus a_2,[i\ge 2]a'_i=a_\),使用 \(n=2\) 的 rhs 把 lhs 兩項縮成一項即可歸到 \(n\leftarrow n-1\) 的子問題

所以根據 \(\rm fwt\) 的定義式子可以進行一些簡單的和式變換:

\[\begin&[x^q]}\left(\sum\limits_^n x^\right)\\

\\&=\sum_^n\prod_(-1)^\&q|}\\

&=\sum_^-1} cnt_(-1)^}(s\&t)}\\

&=[x^t]}\left(\sum\limits_^ cnt_x^i\right)\end

\]第二行到第三行是發生了統計方式的轉化:原來是逐物品列舉,同時將 \(t\) 包含的,給 \(q\) 點值有 \(-1\) 貢獻的 \(j\) 給予 \(-1\) 貢獻,而第三行不過是分類列舉,但是仍然強制在 \(t\) 集合內的 \(j\) 才能產生 \(-1\) 貢獻,因此根據實際含義找到了這樣一組等量關係

事已至此,時間複雜度 \(\theta\left(2^(n+m2^m)\right)\)

const int n=1e5+10,maxs=1<<16;

int n,m,k,w[10],tas[n][10],sw[100];

vectorc[maxs];

signed main()

}for(int i=0;if; f.resize(u);

for(int j=1;j<=n;++j)

f[xsum]++;

}fwt(f,u,1);

for(int j=0;j}

for(int i=0;ifwt(ans,u,-1);

rep(i,0,u-1) print(ans[i]);

return 0;

}

題解 CF1119H Tripe題解

題目傳送門 給出 n,t,x,y,z 值域 le 2 t 給出 n 個三元組 a i,b i,c i 表示有 x 個 a i y 個 b i z 個 c i 對於每個 k in 0,2 t 1 求出從每組選出乙個數的異或值為 k 的方案數。先定義 delta n f delta 表示多項式 f 的第...

CF589H 構造 電話節

鏈結找不到了 發現如果對於乙個聯通塊內的偶數個點,一定可以兩兩配對且不相交 如果相交,則調換組合順序一定可以不相交 而如果我們把所有這些路徑拿出來,邊數一定小於等於聯通塊大小 1 所以直接在任意生成樹上做就好 那麼就dfs一下,判斷一下有沒有奇數個點就好了 dfs過程中,乙個點的子樹中的點最多向上傳...