【題目描述】
你需要維護 \(n\) 個可重整數集,集合的編號從 \(1\) 到 \(n\)。
這些集合初始都是空集,有 \(m\) 個操作:
【輸入/輸出格式】
不關心\(1 \le n,m \le 5\times 10^4\), \(1\le l,r \le n\), \(1\) 操作中 \(|c|\le n\), \(2\) 操作中 \(1\le c < 2^\)
暴力樹套樹
外層維護權值線段樹 內層是區間修改線段樹
每次修改就把包含\(c\)的那些權值線段樹節點上的 每個內層線段樹的\([l,r]\)區間\(+1\)
查詢就在權值線段樹上二分。。。
雖然要區間修改 但是空間其實是不會爆的 一次修改其實最多會新建\(\log^2 n\)個內層線段樹節點(並不會證明)
時間複雜度似乎是\(o(m\log^2 n)\)
p.s. \(c\)可能是負數 注意要加乙個偏移量
#include using namespace std;
inline int read()
int n, m;
//內層線段樹
struct tree tr[15000005];
int tot;
inline void add(int ind, int l, int r, int v)
inline void pushdown(int ind, int l, int r)
void update(int &ind, int l, int r, int x, int y)
pushdown(ind, l, r);
int mid = (l + r) >> 1;
if (x <= mid) update(tr[ind].lc, l, mid, x, y);
if (mid < y) update(tr[ind].rc, mid+1, r, x, y);
tr[ind].sum = (tr[tr[ind].lc].sum + tr[tr[ind].rc].sum);
}int query(int ind, int l, int r, int x, int y)
//外層線段樹
struct tree tr[200005];
int rt, tot, rt[200005];
void update(int &ind, int l, int r, int x, int y, int pos)
int query(int ind, int l, int r, int x, int y, int k)
int main() else
} return 0;
}
BZOJ K大數查詢(分治)(Zjoi2013)
有n個位置,m個操作。操作有兩種,每次操作如果是1 a b c的形式表示在第a個位置到第b個位置,每個位置加入乙個數c 如果是2 a b c形式,表示詢問從第a個位置到第b個位置,第c大的數是多少。第一行n,m 接下來m行,每行形如1 a b c或2 a b c 輸出每個詢問的結果 題目大意 略。思...
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 並且他們的答案 加...