P4310 絕世好題

2022-05-05 19:48:17 字數 1092 閱讀 1068

題目描述

給定乙個長度為n的數列ai,求ai的子串行bi的最長長度,滿足bi&bi-1!=0(2<=i<=len)。

說明對於100%的資料,1<=n<=100000,ai<=10^9。

錯誤日誌: 沒搞清 每一位的dp值如何更新記錄陣列

乙個數 \(a\) 可以接在數 \(b\) 後面, 當他們在二進位制下有相同位同為 \(1\) 時成立

這啟發我們可以這樣更新: 對於新的數 \(x\) 的每個 \(1\) 位,向前尋找乙個最長的數為前乙個轉移

可這樣複雜度任然無法保證

而想想又發現, 不優值一定不考慮, 我們只用對每一位含 \(1\) 位 儲存最大長度即可

我們設定乙個陣列 \(ton[j]\) 表示到目前為止, 二進位制下第 \(j\) 位為 \(1\) 的最長長度

更新第 \(i\) 個數 \(x\) 時, 當 \(x\) 的第 \(j\) 位為 \(1\) 時, 有 \(dp[i] = max(dp[i], ton[j] + 1)\)

更新完答案後需要返回來更新 \(ton[j]\), 當 \(x\) 的第 \(j\) 位為 \(1\) 時, 有 \(ton[j] = max(ton[j], dp[i])\)

#include#include#include#include#include#include#define ll long long

#define rep(i, x, y) for(int i = (x);i <= (y);i++)

using namespace std;

int rd()

while(c >= '0' && c <= '9')

return flag * out;

}const int maxn = 200019;

int num;

int dp[maxn], ton[39];

int ans;

int main()

rep(j, 1, 31)

ans = max(ans, dp[i]);

} printf("%d\n", ans);

return 0;

}

P4310 絕世好題

給定乙個長度為n的數列ai,求ai的子串行bi的最長長度,滿足bi bi 1 0 2 i len 輸入格式 輸入檔案共2行。第一行包括乙個整數n。第二行包括n個整數,第i個整數表示ai。輸出格式 輸出檔案共一行。包括乙個整數,表示子串行bi的最長長度。輸入樣例 1 3 1 2 3 輸出樣例 1 2 ...

P4310 絕世好題 題解

第一次看這道題首先想到的就是時間複雜度為 n 的求最長上公升子串行 for int i 1 i n i 這樣寫會超時 所以我們考慮更優秀的演算法,突破口就是位運算 題目中的操作是按位與,所以我們可以把乙個數的每乙個二進位制位分別拆分進行計算 我們設 f i 為當前二進位制位為 i 時滿足要求的最長長...

P4310 絕世好題 DP 題解

題面傳送門 p4310 絕世好題 第一眼以為是套路n2 dp,一看資料範圍1e5,直接懵逼5min 其實挺簡單的,題目也不錯 仔細想想挺簡單的,因為b i b i 1 0,那至少有一位二進位制位b i 和b i 1 均為1。然後我們考慮列舉bi的每一位二進位制1,在所有這一位也為1的數中,取以該數結...