bzoj4592 SHOI2015 腦洞治療儀

2022-05-31 17:15:14 字數 2549 閱讀 6886

bzoj

洛谷3.20 正解是線段樹,但是今天沒時間寫了,先挖個坑qwq,暫時就寫個\(odt\)

操作0:區間賦值

操作1:查詢區間和,區間賦值

先查詢區間\([l0, r0]\)的和\(sum\),得到可用的腦組織數並將\([l0, r0]\)賦\(0\),然後在\([l1, r1]\)上二分找到位置\(p\),滿足\([l1, p]\)的中\(0\)的個數等於\(sum\)(如果沒有,說明可用腦組織多了,直接把\(p\)設為\(r1\)就行)然後把\([l1, p]\)賦\(1\)

操作2:查詢最長連續子段

複雜度\(o(n \log^2 n)\)

這個題珂朵莉樹能過……bzoj上還跑得飛快……

上面是線段樹,下面是珂朵莉樹……

操作0:直接\(assign\)

操作1:查出\([l0, r0]\)中\(1\)的個數,然後\(assign\),對\([l1, r1]\)暴力跑,找夠了就\(assign\),但是注意不要經常\(split\),這裡的\(assign\)能用之前的迭代器就不要再\(split\)去找了,不然珂朵莉也救不了你qwq($tle$10發的教訓qwq)

操作2:暴力跑一遍區間內節點就好了,要有信仰

另外通過此題發現的\(odt\)注意事項:每次重新\(split\)了右端點之後一定要再\(split\)左端點一次,不然左邊的迭代器可能被刪除(下面的82行,也就是倒數第6行,好像markdown不顯示行號……),這就是luogu上有篇題解會\(re\)的原因

#include #include #include #define maxn 200005

typedef long long ll;

struct segmenttree node[maxn << 2];

void build(int, int, int);

void push_up(int, int, int);

void push_down(int, int, int);

void cover(int, int, int, int, int, int);

int query1(int, int, int, int, int);

int query(int, int, int, int, int);

void fix(int, int, int, int);

node & operator (int x)

};int n, m;

segmenttree tr;

int main() else printf("%d\n", tr.query(1, 1, n, l0, r0));

} return 0;

}void segmenttree::push_up(int id, int l, int r)

void segmenttree::push_down(int id, int l, int r)

}void segmenttree::build(int id, int l, int r)

void segmenttree::cover(int id, int l, int r, int l, int r, int v) else

}int segmenttree::query1(int id, int l, int r, int l, int r)

int segmenttree::query(int id, int l, int r, int l, int r)

}void segmenttree::fix(int l0, int r0, int l1, int r1)

cover(1, 1, n, l1, l, 1);

}//rhein_e

#include #include #include #include #include typedef long long ll;

struct odt_node

odt_node (int p = 0):l(p), r(p), val(0) {}

bool operator

};typedef std::set::iterator iter;

struct odt

iter split(int);

void assign(int, int, char);

int query(int, int);

};void fix(int, int, int, int);

odt odt;

int n, m;

int main() else printf("%d\n", odt.query(l0, r0));

} return 0;

}inline iter odt::split(int pos)

inline void odt::assign(int l, int r, char v)

inline int odt::query(int l, int r)

void fix(int l0, int r0, int l1, int r1) else

}//rhein_e

BZOJ4592 Shoi2015 腦洞治療儀

進行 實際上相當於用1覆蓋一段區間,這段區間內原有的1的個數加上挖出來的1的個數等於這段區間的長度,並且這段區間的長度最長為 的區間長度 知道了一段區間的長度,區間裡有多少1,還剩多少腦組織,就能知道這段區間是否被完全覆蓋 需要判斷是否還剩腦組織,如果沒了就返回,要不然複雜度不對 複雜度 o m l...

BZOJ4592 Shoi2015 腦洞治療儀

bzoj4592 吐槽一下ds y 我 這個資料 了一天我xx x!一開始看到這個題。誒,區間連續最大和誒!把腦洞的值為1,正常的賦為 i nf但是操作1怎麼辦。發現就是先統計出l0 到r0 區間內 i nf的個數to t 然後區間賦為1.然後統計l1 到r1 區間內1的個數to t 如果to t ...

BZOJ 4592 Shoi2015 腦洞治療儀

4592 shoi 2015 腦 洞治療儀 4592 shoi2015 腦洞 儀 4592 shoi 2015 腦洞治 療儀description 曾經發明了自動刷題機的發明家shtsc又公開了他的新發明 腦洞 儀 一種可以 他因為發明而日益增大的腦洞的神秘裝置。為了簡單起見,我們將大腦視作乙個01...