洛谷P3674 小清新人渣的本願

2022-05-06 20:57:09 字數 1276 閱讀 2000

給定序列a,長度為n,有m次操作,opt表示該次操作型別,l,r表示操作的區間,x表示這次操作的x

選出的這兩個數可以是同乙個位置的數。

定義c為每次的x和ai中的最大值,ai >= 0,每次的x>=2。

n,m,c <= 100000

前置技能:

思路:對於此類離線的序列問題,想到莫隊演算法,時間複雜度為\(o(n\sqrt n*(每次轉移複雜度))\)。

n為1e5,若每次轉移複雜度較低,則總時間複雜度可以接受。

難點在於轉移和解的判定。對於每個操作,若暴力轉移,可以用3個陣列,分別記錄當前區間的和、差、積,在移動當前區間端點時,線性的掃一遍區間,更新這三個陣列。這樣每次轉移的複雜度為\(o(n)\) ,總時間複雜度為\(o(n^2\sqrt n)\) ,顯然會tle。

於是需要更優的方法來判定答案並以較低複雜度轉移。實際上,可以在值域上維護乙個集合,表示當前區間內存在的數的種類。對於每種操作,可以通過某種快速的判定方法判斷集合內元素是否滿足要求。

考慮二進位制狀態壓縮,因為n比較大,可以用bitset維護集合,記作s1。

bitset基礎技能

這樣,每次可以\(o(1)\)轉移。

查詢答案:

code

#include using namespace std;

const int n = 100005;

bitsets1, s2, res;//可以再用乙個bitset代替陣列儲存每個詢問的答案 節省空間

int n, m, len, v[n], cnt[n];

struct q q[n];

inline bool cmp(const q &a, const q &b)

inline void add(int p)

inline void del(int p)

int main()

sort(q + 1, q + 1 + m, cmp);

int l = q[1].l , r = l - 1, ql, qr, opt, qx;

for(int i = 1; i <= m; ++i)

for(int i = 1; i <= m; ++i) (res[i]) ? puts("hana") : puts("bi");

return 0;

}

洛谷P3674 小清新人渣的本願

題意 多次詢問,區間內是否存在兩個數,使得它們的和為x,差為x,積為x。n,m,v 100000 解 毒瘤bitset.假如我們有詢問區間的乙個桶,那麼我們就可以做到o n 列舉查詢了。然後我們用bitset優化一下.外面套上莫隊來維護桶。具體來說,差為x可以寫成 a b x 然後我們把bitset...

洛谷P3674 小清新人渣的本願

題目大意 給你 n 個數,m 個詢問 n,m leqslant 10 5 有三種 1 l r x 詢問區間 l,r 內有沒有兩個數相減等於 x 2 l r x 詢問區間 l,r 內有沒有兩個數相加等於 x 3 l r x 詢問區間 l,r 內有沒有兩個數相乘等於 x 注意,兩個數字置可以相同 題解 ...

洛谷 P3674 小清新人渣的本願

給定乙個長度為 n 的陣列 a 有三種詢問 1.詢問是否存在 a i a j x i,j in l,r 2.詢問是否存在 a i a j x i,j in l,r 3.詢問是否存在 a i a j x i,j in l,r 我們使用莫隊來解這道題 對於減法,a i a j x 化簡為 a i a j...