傳送
這題剛開始看到那麼多式子,確實沒啥思路。
但是再仔細想一想會發現挺有意思的。
因為\(b\)序列的限制,每乙個\(b_i\)的二進位制中的1必定只有他自己有,那麼\(\sum b_i\)就是把他們按位與起來。
我們令\(dp[s]\)表示\(\sum b_i=s\)的\(b\)序列個數,那麼答案就是\(dp(i) * \sum phi(i+1)\)。
考慮轉移,我們列舉\(s\),\(s\)的範圍是\(0\)到\(a\)中最大的數所在的二進位制位全是1的數。找到另乙個數\(s'\),且\(s' \& s=0\),表示乙個符合\(b\)序列構造方式的另乙個數加入到了\(b\)中。那麼轉移就是\(dp[s | s'] += dp[s] * num[s']\),\(num[s']\)表示數值為\(s'\)的\(a_i\)個數。
但這麼做,\(s'\)並不是很好找,不能保證複雜度。所以我們換一種列舉方法:列舉\(s | s'\),然後列舉他的子集\(x\),那麼\(x\)就是原來的\(s\),\(s|s' - x\)就是原來的\(s'\)。
不過這麼做還要防止重複列舉,那麼迴圈的時候規定\(x \geqslant s|s'-s\)就行啦。
最後還剩乙個尾巴,就是0怎麼辦,因為\(0\)可以加到任意序列中,那麼如果有\(t\)個0,就把答案乘以\(2^t\)。
#include#include#include#include#include#include#include#include#include#include#includeusing namespace std;
#define enter puts("")
#define space putchar(' ')
#define mem(a, x) memset(a, x, sizeof(a))
#define in inline
#define fore(i, x, y) for(int i = head[x], y; ~i && (y = e[i].to); i = e[i].nxt)
typedef long long ll;
typedef double db;
const int inf = 0x3f3f3f3f;
const db eps = 1e-8;
const int maxn = 1e6 + 5;
const int maxn = 4e5 + 5;
const int mod = 1e9 + 7;
in ll read()
in void write(ll x)
in void myfile()
int n, max = 0;
int prm[maxn], v[maxn], pcnt = 0;
int phi[maxn];
in void init() }}
ll num[maxn], dp[maxn];
in ll add(ll a, ll b)
int main()
int s = 0;
while((1 << s) < max) ++s;
dp[0] = 1;
for(int i = 1; i <= (1 << s); ++i)
for(int j = i; j >= i - j; j = (j - 1) & i)
dp[i] = add(dp[i], dp[i - j] * num[j] % mod);
ll ans = 1;
for(int i = 1; i <= (1 << s); ++i) ans = add(ans, dp[i] * phi[i + 1] % mod);
for(int i = 1; i <= num[0]; ++i) ans = (ans << 1) % mod;
write(ans), enter;
return 0;
}
NOI Online 3 提高組 優秀子串行
點此看題 首先有乙個樸素dpdp dp,因為每個數字都只會最多出現1 11次,而且出現數字相同的不同情況最後也可以一起算答案 和一定 那麼我們只需要統計出方案數,dp i dp i dp i 為二進位制位出現的裝壓為i ii,轉移列舉包含i ii的狀態j jj,設a i a i a i 為值i ii...
NOI Online 3 提高組 水壺
在乙個長度為 n 的序列中求出長度為 k 1 的最大子段。本題唯一的需要注意的一點是當 k n 時要輸出所有數的和,像我的考場 scanf d d n,k k if k n k n for int i 1 i n i scanf d a i for int i 1 i k i op a i for ...
NOI Online 3 提高組 魔法值
我是真沒想到可以用 flo yd floyd floy d 好吧其實也不是正宗的吧 感覺這個演算法已經被我遺忘了 qwq qwqqw q。結果考場上把快速冪又打爆了 定義 to i j k to i j k to i j k 為 i ii 到 j jj 的路徑長度為 2 k2 k 2k的方案總數,d...