Time Limit Exceeded(高維字首和)
題意
題目的意思是給一個數組C,長度為n,每個數字的範圍是2^m,然後要求構造一個數組a,滿足
1、a[i] % C[i] !=0 ;
2、a[i] < 2^m ;
3、a[i] & a[i+1] = 0;
Sol
直接dp的話就是先列舉補集的子集,這樣的複雜度是\(3^n\)的
然後補集的子集可以用高位字首和優化一下
時間複雜度:\(O(2^n * n)\)
#include<cstdio> #include<cstring> using namespace std; const int MAXN = 1e5 + 10, mod = 1000000000; inline int read() { char c = getchar(); int x = 0, f = 1; while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();} while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar(); return x * f; } int N, M, a[MAXN], c[MAXN], f[51][65537], sum[51][65537]; int add(int &x, int y) { x = (x + y >= mod ? x + y - mod : x + y); } int solve() { N = read(); M = read(); int Lim = (1 << M) - 1; memset(f, 0, sizeof(f)); memset(sum, 0, sizeof(sum)); f[0][0] = 1; for(int i = 0; i <= Lim; i++) sum[0][i] = 1; for(int i = 1; i <= N; i++) { c[i] = read(); for(int sta = 1; sta <= Lim; sta ++) { if(!(sta % c[i])) continue; int s = (~sta) & Lim; sum[i][sta] = f[i][sta] = sum[i - 1][s]; } for(int j = 0; j < M; j++)//必須先列舉這個 for(int sta = 0; sta <= Lim; sta++) if(sta & (1 << j)) add(sum[i][sta], sum[i][sta ^ (1 << j)]); } int ans = 0; for(int i = 0; i <= Lim; i++) add(ans, f[N][i]); return ans; } int main() { int T = read(); while(T--) printf("%d\n", solve()); return 0; }
相關推薦
Time Limit Exceeded(高維字首和)
題意 題目連結 題目的意思是給一個數組C,長度為n,每個數字的範圍是2^m,然後要求構造一個數組a,滿足 1、a[i] % C[i] !=0 ; 2、a[i] < 2^m ; 3、a[i] & a[i+1] = 0; Sol 直接dp的話就是先列舉補集的子集,這樣的複雜度是\(3
TLE Time Limit Exceeded 高維字首和
題意:給出長度為n的序列c,求非負整數序列a,滿足a<2^m,並且有a[i]&a[i+1]=0,對於每個a[i],要保證a[i]不是c[i]的倍數,求這樣的a[i]序列的個數 思路:d
SPOJTLE - Time Limit Exceeded(高位字首和)
題意 題目連結 題目的意思是給一個數組C,長度為n,每個數字的範圍是2^m,然後要求構造一個數組a,滿足 1、a[i] % C[i] !=0 ; 2、a[i] < 2^m ; 3、a[i] & a[i+1] = 0; Sol 直接dp的話就是
SPOJ.TLE - Time Limit Exceeded(DP 高維字首和)
題目連結 \(Description\) 給定長為\(n\)的陣列\(c_i\)和\(m\),求長為\(n\)的序列\(a_i\)個數,滿足:\(c_i\not\mid a_i,\quad a_i\&a_{i+1}=0\)。 \(n\leq 50,m\leq 15,0\leq a_i<2^m
【高維字首和】SPOJ(TLE)[Time Limit Exceeded]題解
題目概述 題目名稱要不要這麼奇葩而且和題面沒有半毛錢關係啊,我上交題目都以為自己TLE了。 給出 nn 個數 cici ,現在需要構造 aiai 使得: aimodci>0aimodci&
Time Limit Exceeded錯誤的原因
很多時候我們看到Time Limit Exceeded馬上會想到一定是演算法太慢,不符合要求,其實往往還可能遇到一種情況是沒有判斷輸入結束,不然 系統一直在那等你的輸出結果,發現你一直不輸出,或者程式一直不退出,所以給Time Limit Exceeded。 比如讓你輸入整數n,然後輸入n組
BZOJ:5092 [Lydsy1711月賽]分割序列(貪心&高維字首和)
Description 對於一個長度為n的非負整數序列b_1,b_2,...,b_n,定義這個序列的能量為:f(b)=max{i=0,1,...,n}((b_1 xor b _2 xor...xor b_i)+(b_{i+1} xor b_{i+2} xor...xor b_n))
HihoCoder - 1496:尋找最大值(高維字首和||手動求子集)
描述 給定N個數A1, A2, A3, ... AN,小Ho想從中找到兩個數Ai和Aj(i ≠ j)使得乘積Ai × Aj × (Ai AND Aj)最大。其中AND是按位與操作。 小Ho當然知道怎麼做。現在他想把這個問題交給你。 輸入 第一行
牛客網 NOIP賽前集訓營-普及組(第四場)C--部分和 (高維字首和)
傳送門 解題思路 高維字首和模板題。首先,求字首和有兩種方式,比如說對於求二維字首和來說。 第一種 : for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) sum[i][j]=sum[i-1][j]+sum[i][j-1]-s
高維字首和
高維字首和就是求關於一個集合子集(或超集)的狀態的和 牛客有一道題寫的很好 傳送門 題面就已經說明了高維字首和的原理 連結:https://ac.nowcoder.com/acm/contest/167/C 來源:牛客網 對於一個一維陣列求部分和,可以使用如下程式碼 for
bzoj 5092 分割序列 —— 高維字首和
題目:https://www.lydsy.com/JudgeOnline/problem.php?id=5092 首先,處理出異或字首和 s[i],i 位置的答案就是 s[j] + s[j]^s[i],j <= i 異或的套路是按位考慮,但是這裡有加法...怎麼考慮進位? 所以就不能考慮答案的這一
bzoj 5092 [Lydsy1711月賽]分割序列——高維字首和
題目:https://www.lydsy.com/JudgeOnline/problem.php?id=5092 套路地弄一個字首異或和,就變成 f[ i ]=max_{j=0}^{i} { s[ j ] + (s[ i ]^s[ j ]) }。再套路地考慮按位貪心。 然後看了題解。按位貪心不是確定 f[
[JZOJ5952] 凱旋而歸 ([BZOJ 5092]【Lydsy1711月賽】分割序列)【高維字首和】【DP】
Description 對於一個長度為m的序列a,記 f ( a
BZOJ5092:[Lydsy1711月賽]分割序列(貪心,高維字首和)
Description 對於一個長度為n的非負整數序列b_1,b_2,...,b_n,定義這個序列的能量為:f(b)=max{i=0,1,...,n}((b_1 xor b_2 xor...xor b_i)+(b_{i+1} xor b_{i+2} xor...xor b_n))其中xor表示按
luoguP3175 [HAOI2015]按位或 min-max容斥 + 高維字首和
考慮min-max容斥 \(E[max(S)] = \sum \limits_{T \subset S} min(T)\) \(min(T)\)是可以被表示出來 即所有與\(T\)有交集的數的概率的和的倒數 通過轉化一下,可以考慮求所有與\(T\)沒有交集的數的概率和 即求\(T\)的補集的
hihocoder1496-高維字首和|暴力
http://hihocoder.com/problemset/solution/1115709 其實我感覺高維字首本身也是一種暴力(遞推???)。。。 因為&操作不會使1的數量增加,所以我
Time Limit Exceeded的原因及避免方法
經常會遇到這種令人抓狂的情況 自己編寫的程式在codeblocks上怎麼編譯執行都能輸出正確結果 然而一提交,卻無法Accept,很多時候顯示的並不是Wrong Answer 而是比WrongAnswer更令人絕望的 。 在oj中,給定的Time Limit 是1
cf449D. Jzzhu and Numbers(容斥原理 高維字首和)
題意 題目連結 給出\(n\)個數,問任意選幾個數,它們\(\&\)起來等於\(0\)的方案數 Sol 正解居然是容斥原理Orz,然而本蒟蒻完全想不到。。 考慮每一種方案 答案=任意一種方案 - 至少有\(1\)位為\(1\)的方案 + 至少有兩位為\(1\)的方案 - 至少有三位為\(1\)的方案
LeetCode第五題答案(time limite exceeded) C++ time limit exceeded
這個是最開始寫的brutal answer. 遍歷所有子串,演算法效率不高,雖然結果正確,但在LeetCode上time limit exceeded。下一篇附上改進程式碼。 class Solution { public: bool isPalindromic(s
5765 Bonds 高維字首和
這題做了好久,,看了網上的題解也看不太懂,,只知道用高維字首做,,,,,,然後在拉粑粑的時候,,突然想出了一種方法 他是要算出每條邊出現在多少割集中,,,我們可以反著想,,我們可以先算出有多少割集(個數設為sum),在算出這條邊包含多少合法聯通塊中(個數設為x),,然後s