題目傳送門
題目大意:給你乙個序列,定義乙個子串行的權值表示子串行中元素的異或和,現在讓你選出兩個互不相交的子串行,求選出的這兩個子串行權值相等的方案數,$n,a_\leq 10^$
這是一道考察對$fwt$演算法理解的好題。然而我並不會
思路來自出題人的題解
假設權值最大值為$m$
暴力怎麼搞?揹包$dp$一下
定義$f(i,j)$表示現在遍歷到了第$i$個元素,選出的兩個子串行異或和為$j$的方案數,容易得到方程:
$f(i,j)=f(i-1,j)+2*f(i-1,j\;xor\;a_)$
時間複雜度$o(nm)$,可以獲得30分
看那個卷積形式,$fwt$?
時間複雜度$o(nmlogm)$,可以獲得..0分
我們發現每一層的生成函式裡只有兩個位置有值
假設現在我們遍歷到了第$i$個物品$a_$,第$i$層的生成函式長這個樣:
$f_(0)=1, f_(a_)=2$
其它位置都是0誒
對它進行fwt正變換,會發現正變換之後的陣列裡只有-1和3
因為$f_(0)$對每個位置都有+1的貢獻,而$f_(a_)$對每個位置有+2或-2點貢獻
重新考慮那個$0$分暴力。我們把每一層都正變換,然後對應位置相乘,再逆變換回來
我們可以想辦法快速求出對應位置相乘之後的陣列$f$,這樣再用一次逆變換就行了
我們只需要統計出每個位置上有幾個3相乘,設3的數量是$x$,-1的數量就是$n-x$,快速冪一下,就能得到$f$了
我們把貢獻積轉化成了指數上的貢獻和,發現只用一次正變換就行啦!
再用快速冪把貢獻和轉化成貢獻積。最後逆變換回來就行了
時間$o(mlogm)$
1 #include 2 #include 3 #include 4#def_ne n1 (1<<20)+10
5#def_ne ll long long
6using
namespace
std;
7const
int p=998244353;8
9 template void read(_t &ret)
1013
while(c>='
0'&&c<='9')
14 ret=ret*fh;15}
1617
ll qpow(ll x,ll y)
1823
24void fwt_xor(int *s,int len,int
type)
2534}35
36int
n,ma,len,l;
37int
a[n1],s[n1];
3839
intma_n()
4053 fwt_xor(s,len,-1
);54 printf("
%d\n
",(s[0]-1+p)%p);
55return0;
56 }
uoj 310 UNR 2 黎明前的巧克力
題目描述 題解 考慮到選出的兩個集合的異或值為 0 所以我們可以看做找出集合,其異或值為 0 然後如果這個集合大小是 x 對答案的貢獻就是 2 x 所以我們考慮每個 i 對應乙個多項式 1 2x 只要我們把多項式乘起來即可 我們考慮 fwt 過程中 i 位置上的數對 j 位置的貢獻是數值乘上 1 不...
C UNR 2 黎明前的巧克力
evan 和 lyra 都是聰明可愛的孩子,兩年前,evan 開始為乙個被稱為uoj的神秘的oi組織工作,在 evan 與其他小夥伴的努力下,uoj不僅成了oi界原創比賽的典範,更是因ur這一 難度的存在而舉世聞名。然而今年,隨著 evan 前往世界彼岸,uoj一天天減少著他的活力,而就在oi歷新年...
UNR 2 黎明前的巧克力
解題思路 考慮乙個子集 s 的異或和如果為 0 那麼貢獻為 2 不難列出生產函式的式子,這裡的卷積是異或卷積。x 0 prod 2x 1 因為每一項只有兩項 x 0,x 有值,記 f i x 2x 1 f i x textf x 有 f i x sum 1 2 times 1 x s 不難發現 f ...