CQOI2018 交錯序列 (矩陣快速冪,數論)

2022-04-28 19:36:10 字數 1424 閱讀 8160

這一題出得真的很好,將原本一道矩陣快速冪硬生生加入組合數的標籤,還那麼沒有違和感,那麼讓人看不出來。所以做這道題必須先知道(矩陣快速冪及如何構建遞推矩陣)(組合數及二項式定理)。

不知道大家有沒有做過洛谷的帕秋莉手環p哥的桶,這道題中不能有相鄰的兩個1就是我們在構造這個交錯序列時不能連續加入兩個1,這個如果直接讓我們求方案數(不靠慮一的個數)就是矩陣快速冪的板子了(可以自己推遞推方程)。但是這1題偏偏把1的個數搭上了,我們發現1的個數是可以達到 $ 10^8 $ 級別的!所以我們不能直接把1得個數當做乙個狀態,這裡有乙個巧妙的避開1的個數的遞推方程:

因為我們狀態轉移時,我們其實只需要知道序列末尾是1還是0,而1的個數我們不妨不管(為什麼要折磨自己呢?)我們可以用 $ f[i][j][0/1] $ 為前 $ i $ 位,最後一位為 $ 0/1 $ ,滿足條件的序列的1的個數的j次方和(注意是j次方和)。然後我們就可以避開1的個數(因為每一次我們如果要在序列末尾加乙個1,就相當於所有長度為i的末尾為一的序列都要加上乙個1,然後我們只要求 $ (y+1)^j $ 即可!這個可以用二項式定理搞一下)(這樣建出來的矩陣只有90*90可以勉強過)(需要卡常)

後效性:我們避開了一的個數,但是我們需要求零得個數啊!這又怎麼辦呢?我們把題目要我們求的東西轉化一下: $ xayb=(n-y)ayb=\sum_c(a,i)ni(-y)yb $ 這樣我們就可以用我們之前設的(滿足條件的序列的1的個數的j次方和)的這一維狀態求解了!

卡常:因為這一題的模數小於 $ 10^8 $ 不是 $ 10^9 $ 我們矩陣乘法的時候可以多加幾次再取模(詳情看**),不然真的很難卡常數!

#include#include#include#include#include#include#include#include#include#include#include#include#define ull unsigned long long

#define ll long long

#define db double

#define inf 0x7fffffff

#define rg register int

using namespace std;

int n,a,b,m,t,f,tot;

int c[93][93],nf[95];

struct su

int main()

for(rg i=0;i<=a;++i)printf("%d\n",(tot+m)%m);

return 0;

}

CQOI2018 交錯序列

這個題簡直有毒,o a b 3logn 的做法不卡常只比 o 2 n n 多 10 分 看到 a 和 b 簡直小的可憐,於是可以往矩陣上聯想 發現這個柿子有些特殊,好像可以二項式定理搞一搞 於是 x ay b 可以寫成 n y ay b 於是接下來就二項式定理好了 n y ay b sum a bi...

CQOI2018 異或序列

哈哈哈我竟然秒切了省選題 莫隊 異或。考慮異或的性質,乙個數同時異或兩次等於沒有進行操作。那麼我們設a i 為前i個數的異或和,顯然對於乙個區間 l,now a l 1 oplus a now 就是這個區間裡面所有的數的異或和。如果 a l 1 oplus a now k 那麼ans 這等同於 a ...

CQOI 2018 異或序列

給出乙個長為 n 的數列 a 和 k 多次詢問 對於乙個區間 l i,r i 問區間內有多少個不為空的子段異或和為 k 注意到一件有趣的事,就是每次詢問的 k 相同。因為 a oplus a 0 所以子段異或問題可以看作字首異或和的異或,即 a i oplus a i 1 oplus.oplus a...