1. 程式人生 > >Time Limit Exceeded(高維字首和)

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[

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