啟智樹提高組Day4T3 2的冪拆分

2022-09-17 00:33:11 字數 2652 閱讀 3171

問把 \(n\) 拆分成2的冪的和的形式的方案數。注意拆分是無序的,即 \(2^0,2^2,2^1,2^0\) 和 \(2^0,2^0,2^1,2^2\) 是一種方案。\(n \le 10^\)

定義:

\[s_k(n)=\sum_^i^k

\]\[\]

部分下取整符號可能有遺漏。

首先通過打表發現前幾項是:(從0開始)

\[1,1,2,2,4,4,6,6,10,10,14,14,20,20,26,26,...

\]發現去重差分還是原陣列,並且發現:

\[f_i = f_ ,i \bmod 2=1

\]\[f_i = f_+f_,i\bmod2=0

\]不斷重複使用這兩個式子拆開發現:

\[f_ = \sum_^f_j

\]拆 \(f_j\) 發現:

\[f_n=\sum_^\sum_^f_i

\]\[=\sum_^ f_i\sum_^1

\]\[=\sum_^f_i(s_(\left \lfloor n/2 \right \rfloor +1)-s_0(2i))

\]\[=s_0(\left \lfloor n/2 \right \rfloor +1)\sum_^f_i-\sum_^f_is_0(2i)

\]\[=s_0(\left \lfloor n/2 \right \rfloor +1)\sum_^f_i-2\sum_^f_ii

\](公式不太好打,就不打那麼多了)

發現前面的那部分可以直接遞迴子問題,我們難以解決的是後邊的那個類似 \(\sum_^f_ii^k\) 的式子。我們試圖求解這個式子:

\[f(n,k)=\sum_^nf_ii^k

\]\[=\sum_^ni^k\sum_^f_j

\]\[=\sum_^f_j \sum_^ni^k

\]\[=\sum_^f_j(s_k(n+1)-s_k(2j))

\]\[=\sum_^f_js_k(n+1)-\sum_^f_j\sum_^\frac}b_(2j)^d

\]\[=\sum_^f_js_k(n+1)-\sum_^\frac}b_2^d \sum_^f_jj^d

\]\[=f(n/2,0)s_k(n+1)-\sum_^\frac}b_2^d f(n/2,d)

\]發現左邊是子問題,右邊每次需要的 \(k\) 會加一。因此 \(k\) 最多是 \(logn\)。狀態數 \(o(log^2n)\),轉移複雜度 \(o(logn)\),總複雜度:\(o(log^3n)\)。由於 \(k\) 比較小,不需要多項式求逆加速求 \(b_i\),且這並不是複雜度瓶頸。

注意最好手寫個雜湊表,不然用 stl map 可能會被卡常。

\(code:\)

#include #include #include #include #include #include #include #include #define n 76

typedef long long ll;

template inline void read(t &x)

while (isdigit(c))

if (flag) x = -x;

}using namespace std;

const int p = 1e9 + 7;

inline void max(int &a, int b)

ll c[n][n], b[n];

inline ll quickpow(ll x, ll k)

return res;

}ll inv[n];

inline ll get_c(int n, int m)

inline void init_b()

} b[0] = 1;

for (register int i = 1; i <= up; ++i)

b[i] = (p - inv[i + 1] * b[i]) % p; }}

const int pp = 13331;

struct hashtable e[n << 1];

int head[pp + 1000], ecnt;

inline void init()

inline void addedge(ll v, int val) ;

head[mirr] = ecnt;

} inline int find(ll v)

return -1;

}}hash;

int mtot;

ll memo[n << 1][n];

ll calc(ll n, int k)

return memo[mirr][k] = (k == 0 ? 2 : 1);

} ll res = 0, tmp = (n + 1) % p;

for (register int d = 1; d <= k + 1; ++d)

res = res * calc(n >> 1, 0) % p;

for (register int d = 1; d <= k + 1; ++d)

return memo[mirr][k] = res;

}ll n;

inline void work()

int main()

return 0;

}

啟智樹衝省隊組Day4T3 疏散

一棟大樓中 10 5 個人緊急疏散。大樓可以被視作網格圖 正檢視 有三個區域,由兩個寬為 1 的樓道隔開。走出樓道最下面即為離開。同一時刻乙個位置只能有乙個人。左右區域的人不能互相串。每個人每一秒能移動一格。問所有人離開所需的最小時間 這題正解比暴力好寫 一般貪心題都這樣 因此考場上沒想到貪心就很難...

啟智樹提高組Day3 T3 pancake

現有 n 個線段,第 i 個線段長度為 l i 現最多可以切 k 刀,只能在整數字置切。要求最小化切完後所有線段的長度的平方和。又有 q 次操作,每次將 k 加一或減一,或者新加一段長為 l i 的線段。每次問最小的平方和。n,q,l i,k le 10 5 保證答案不爆 long long 首先 ...

省選模擬賽Day4T3迂迴

problem problem problem problem problem problem problem problem 3 迂迴 tour tour tour tour tour tour 題目描述 題目描述 給定一有向圖,邊長均為 1,求 長度 小於 k的環個數 mod m 保證 有向圖中...