問題描述
給你乙個長度為n的數列,元素編號1到n,第i個元素值為ai。現在有m個形如(l,r)的提問,你需要回答出區間[l,r]的mex值。即求出區間[l,r]中沒有出現過的最小的非負整數。輸入格式
第一行,兩個整數n和m輸出格式第二行,n個空格間隔的整數,表示數列a
接下來m行,每行兩個整數l,r,表示一次詢問
m行,每行乙個整數,表示對應詢問的答案。樣例輸入
7 5樣例輸出0 2 1 0 1 3 2
1 3
2 3
1 4
3 6
2 7
3資料範圍0 3 2 4
1<=n,m<=200000由於沒有修改操作,可以考慮離線演算法。0<=ai<=200000
1<=l<=r<=n
首先考慮暴力的做法。對於固定的左端點,如何用o(
n)的方法求出左端點與右端點形成的mex陣列的值?用乙個mark陣列從下到大依次列舉沒有出現過的數值即可。考慮到mex陣列單調不減,均攤時間複雜度o(
n)。如果詢問區間的左端點只有乙個,那麼就能像這樣o(
n)解決。
然而本題的左端點是任意的。但是根據離線演算法的基本操作,我們可以把討論有序化。不妨將詢問按左端點從小到大排序。現在假設我們已經求出了以i為左端點的所有區間的mex值,想要得到以i+1為左端點的所有區間的mex值,考慮兩種狀態如何轉移。
從i到i+1,只有乙個不同:那就是有些區間裡本來有ai
,但現在沒有了。顯然只有這樣的區間才會受到一定影響。「這樣的區間」是哪些區間呢?在以i+1為左端點的區間中,這樣的區間是右端點在下乙個ai
出現前的區間,用乙個鍊錶可以方便地維護。
這些區間會受到怎樣的影響?考慮ai
與mex
j 的大小關係。如果me
xj比a
i 要大,那麼把me
xj更新為ai
;否則ai
就不會對me
xj的值產生影響。這樣做問題就解決了。處理區間修改問題,使用線段樹。
1預處理:
(1)用o(
n)將以1為左端點的mex值預處理出來;
(2)預處理出每個數下一次出現的位置;
(3)按區間左端點將詢問排序;
2.從1到n由小到大討論。處理完以i為左端點的詢問後,對me
x 陣列進行區間修改。
**:
#include#include#include#define maxm 200005
#define maxn 200005
#define maxt 800005
using namespace std;
int n,m,a[maxn],mex[maxn],ans[maxm],nex[maxn],las[maxn];
bool mark[maxn];
struct nodeqry[maxm];
bool operator<(node x,node y)
int build(int x,int y)
ls[p]=build(x,mid);
rs[p]=build(mid+1,y);
v[p]=min(v[ls[p]],v[rs[p]]);
return p;
}void modify(int p,int l,int r,int k)
int mid=a[p]+b[p]>>1;
modify(ls[p],l,r,k);
modify(rs[p],l,r,k);
}int getans(int p,int k)
int main()
for(i=1;i<=m;i++)scanf("%d%d",&qry[i].l,&qry[i].r),qry[i].id=i;
for(i=1;i<=n;i++)
sort(qry+1,qry+m+1);
memset(lazy,-1,sizeof(lazy));
build(1,n);
for(i=1,j=1;i<=n&&j<=m;i++)
modify(1,1,nex[i]-1,a[i]);
}for(i=1;i<=m;i++)printf("%d\n",ans[i]);
}
hdu 4747 Mex 線段樹區間更新
有大神部落格在。mex有兩個特徵,乙個是最小,乙個是不在集合中 首先可以看出mex是遞增的 刪掉乙個數a i 對mex l,r r對l i的影響是,a i 不在集合中了,在a i 下次出現之前,那些大於a i 的mex j 都可以被減小至a i 話說線段樹區間更新每次都寫挫 一開始pushdown ...
mex(線段樹 離散化)
題目描述 給你乙個無限長的陣列,初始的時候都為0,有3種操作 操作1是把給定區間 l,r l,r l,r 設為1,操作2是把給定區間 l,r l,r l,r 設為0,操作3把給定區間 l,r l,r l,r 0,1反轉。l r 一共n個操作,每次操作後要輸出最小位置的0。l,r 題解 l r 經過分...
Mex(線段樹的巧妙應用)
題目要求求某段區間第乙個沒有出現的數 0,1,2,3.對於所有的區間,我們把這樣的數加起來最後得到乙個結果。首先,我們要求出這樣的數,然後還得列舉出所有的區間,複雜度太大了。換種思路,我們定住l,是不是一次效能求出所有的r所得出的結果,這就用到線段樹的性質了,因為在移動l的過程中,移一步只變化乙個數...