有乙個長度為n
nn的陣列
\。m
mm次詢問,每次詢問乙個區間內最小沒有出現過的自然數。
對1 −n
1-n1−
n這裡能夠的每個數x
xx,都統計出來在陣列中出現的位置,並在前補上0
00,在後補上n+1
n+1n+
1.例如陣列
\,其中1
11出現過的位置就是:
\其中2
22出現過的位置就是:
\其中3
33出現過的位置就是:
\其中4
44出現過的位置就是:
\其中5
55出現過的位置就是:
\如果乙個自然數x
xx沒有在乙個區間[l,
r]
[l,r]
[l,r
]中出現過,那麼必然存在x
xx的出現序列中的兩個位置p1,
p2
p_1,p_2
p1,p2
滿足p
1<
l<
r
p_1p1
<
l<
r.那麼這就變成乙個經典的2
22維數點問題啦!
我們把每個x
xx的出現位置序列,相鄰兩個數並成乙個二維數點,插入到線段樹中去.
對於每個詢問(l,
r)
(l,r)
(l,r
)
1<
l<
r
p_1p1
<
l<
r條件的權值最小的點就可以了.
將所有的詢問(l,
r)
(l,r)
(l,r
)和數點p1,
p2
p_1,p_2
p1,p2
按照第二維排序,從左往右列舉,遇到詢問就回答,遇到數點就插入.
排序可以省掉一維.
#include
#include
#include
#include
#include
#define pr(x) std::cout << #x << ':' << x << std::endl
#define rep(i,a,b) for(int i = a;i <= b;++i)
#define repi(i,a,b) for(int i = a;i >= b;--i)
#define clr(x) memset(x,0,sizeof(x))
#define setinf(x) memset(x,0x3f,sizeof(x))
const
int n =
200010
;const
int inf =
1e9+7;
int n,m;
int a[n]
;std::map<
int,
int> map;
struct node
}ns[n<<2]
;struct que
bool
operator
<
(const que &q)
const
}qs[n]
,qs2[n<<2]
;int ans[n]
;node maintain
(node &lch,node &rch)
void
change
(int o,
int l,
int r,
int pos,
int val)
int mid =
(l + r)
>>1;
if(pos <= mid)
change
(o<<
1,l,mid,pos,val)
;else
change
(o<<1|
1,mid+
1,r,pos,val)
;
ns[o]
=maintain
(ns[o<<1]
,ns[o<<1|
1]);
}node query
(int o,
int l,
int r,
int ql,
int qr)
void
build
(int o,
int l,
int r)
int mid =
(l + r)
>>1;
build
(o<<
1,l,mid)
;build
(o<<1|
1,mid+
1,r)
; ns[o]
=maintain
(ns[o<<1]
,ns[o<<1|
1]);
}int
main()
rep(i,0,
2*n)
std::
sort
(qs2,qs2+cc)
;rep
(i,1
,m)
std::
sort
(qs+
1,qs+
1+m)
;int pos =0;
rep(i,
1,m)
node res =
query(1
,0,n+1
,qs[i]
.r+1
,n+1);
ans[qs[i]
.id]
= res.num;
}rep
(i,1
,m)}
洛谷P4137 求區間mex
n個數 給m個詢問 每個詢問問這個區間的自然數mex 很久以前做得 有些忘了 首先我們要離散化 mex只可能是 0 a i a i 1 我們把這些值離散化 然後用主席樹維護每種值出現的最晚位置 取min 詢問就是 在r的這顆樹上面 出現最晚位置小於l的最小值 直接在主席樹上二分即可 includeu...
洛谷P5631 最小mex生成樹
給定 n 個點 m 條邊的無向連通圖,邊有邊權。設乙個自然數集合 s 的 text 為 最小的 沒有出現在 s 中的自然數。現在你要求出乙個這個圖的生成樹,使得其邊權集合的 text 盡可能小。n leq 10 6,m leq 2 times 10 6,w i leq 10 5 很套路的線段樹分治。...
線段樹2 洛谷p3373 線段樹
題目位址 解釋 多了乙個乘法操作,可以考慮優先順序。每次先算乘法。首先,對於乙個區間 和為s 假設已經按 a 乘b進行了操作。值得到的值為 s a b sb ab 假設先乘得到 sb a 這樣相比,add應該還要再乘上乙個b才對,所以,當更新到乙個區間時,為了進行先乘的操作而不讓結果發生變化,應該將...