目錄曾經光輝無限的省選題......
竟然是二刷。
傳送門 to luogu
先考慮對於單個詢問,我們只需要二分答案,然後看一下比這個答案大的數有多少即可。
然後我們將所有詢問用整體二分來做,處理到當前值域區間 \([l,r]\),也就相當於我們二分了乙個 \(mid\),對於這個 \(mid\),將所有操作一中插入值大於 \(mid\) 的操作對應的區間整體加一,對於詢問操作直接查詢即可。
但是需要注意乙個細節 —— 當詢問操作被下放到左區間時,對應查詢的 \(rank\) 應該要減去這一次二分後查詢的結果,這個可以模擬平衡樹。
using namespace elaina;
const int maxn=5e4;
const int maxm=5e4;
const ll maxa=(1ll<<62)-1+(1ll<<62);
namespace tree
inline void clear(const int i)
inline void pushdown(const int i,const int l,const int r)
} inline void pushup(const int i)
void modify(const int l,const int r,const int i,const int l,const int r)
int mid=(l+r)>>1,cntl=0,cntr=0;
tree::clear(1);
for(int i=ql;i<=qr;++i)else tmpl[++cntl]=opt[i];
} else{
ll ret=tree::query(opt[i].l,opt[i].r,1,1,n);
// the value mid is too big
if(ret除了整體二分之外,還用到乙個比較經典的 \(\tt trick\).
先二分乙個值,對於這個值來說,大於它的記為 \(1\),其他看做 \(0\),這樣就將原來參差不齊的陣列變成了 \(01\) 陣列,比起原來的陣列更好處理,如果詢問單點只需要再加上乙個 \(\log\).
ZJOI2013 K大數查詢
有n個位置,m個操作。1 a b c形式,表示在第a個位置到第b個位置,每個位置加入乙個數c 2 a b c形式,表示詢問從第a個位置到第b個位置,第c大的數是多少。區間的第k大值有一種二分的做法。二分答案mid,計算出區間內 mid的值有多少個。若數量小於c,則ans mid,否則ans mid。...
ZJOI2013 K大數查詢
有n個位置,m個操作。操作有兩種,每次操作如果是 2 a b c 表示詢問從第a個位置到第b個位置,第c大的數是多少。輸入格式 第一行n,m接下來m行,每行形如1 a b c或2 a b c 輸出格式 輸出每個詢問的結果 solution 整體二分。假設我們現在要解決 ql,qr 並且他們的答案 加...
ZJOI2013 K大數查詢
點此看題 0x01 樹套樹 這道題的思路特別巧妙,樹套樹不一定要用區間線段樹套權值線段樹,還可以反過來套。我們維護乙個動態開點的權值線段樹,每個點代表權值 l,r l,r l,r 在整個區間的出現情況,套上乙個動態開點的區間線段樹,操作1 11對權值線段樹單點修改,然後對每個點的 a,b a,b a...