BZOJ 3339 Rmq Problem(离线+线段树+mex函数)

题意:

q次询问,问[l,r]子区间的mex值

思路:

对子区间[l,r],当l固定的时候,[l,r]的mex值对r单调不减

对询问按照l离线,对当前的l,都有维护一个线段树,每个叶节点保存[l,r]的mex

l每增大1,都要更新[l, next[l]-1],将这个区间内大于a[l]的值更新为a[l]

其中next[i]为i之后的下一个a[i]位置

代码:

线段树写的不熟。。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
#include<stack>
#include<queue>
#include<deque>
#include<set>
#include<vector>
#include<map>

#define fst first
#define sc second
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lc root<<1
#define rc root<<1|1
//#define lowbit(x) ((x)&(-x)) 

using namespace std;

typedef double db;
typedef long double ldb;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PI;
typedef pair<ll,ll> PLL;

const db eps = 1e-6;
const int mod = 1e9+7;
const int maxn = 2e6+100;
const int maxm = 2e6+100;
const int inf = 0x3f3f3f3f;

const db pi = acos(-1.0);

int a[maxn];
int n, q;
int nx[maxn];
int lst[maxn];
struct node{
    int l, r;
    int id;
}b[maxn];
bool cmp(node a, node b){
    return a.l<b.l;
}
int mex[maxn];
set<int>s;
int dat[maxn];
void build(int l, int r, int root){
    int mid = (l+r)>>1;
    if(l==r){
        dat[root] = mex[l];
        return;
    }
    dat[root] = inf;
    build(lson);
    build(rson);
    return;
}
void pushdown(int l, int r, int root){
    if(l==r)return;
    dat[lc]=min(dat[lc],dat[root]);
    dat[rc]=min(dat[rc],dat[root]);
    return;
}
int ask(int x, int l, int r, int root){
    if(dat[root]!=inf)pushdown(l, r, root);
    if(l==r)return dat[root];
    int mid = (l+r)>>1;
    if(x<=mid)return ask(x,lson);
    return ask(x,rson);
}
void update(int x, int y, int val, int l, int r, int root){
    if(dat[root]!=inf)pushdown(l,r,root);
    if(l==x&&y==r){
        dat[root]=min(dat[root],val);return;
    }
    int mid = (l+r)>>1;
    if(y<=mid)update(x,y,val,lson);
    else if(x>mid)update(x,y,val,rson);
    else{
        update(x,mid,val,lson);
        update(mid+1,y,val,rson);
    }
    return;
}
int ans[maxn];
int main(){
    scanf("%d %d", &n, &q);
    for(int i = 1; i <= n; i++){
        nx[i]=n+1;
    }
    for(int i = 1; i <= n; i++){
        scanf("%d", &a[i]);
        if(lst[a[i]]){
            nx[lst[a[i]]]=i;
        }
        lst[a[i]]=i;
    }
    int tmp = 0;
    
    for(int i = 1; i <= n; i++){
        s.insert(a[i]);
        while(s.find(tmp)!=s.end()){
            tmp++;
        }
        mex[i]=tmp;
    }build(1,n,1);
    for(int i = 1; i <= q; i++){b[i].id=i;
        scanf("%d %d", &b[i].l, &b[i].r);
    }
    sort(b+1,b+1+q,cmp);
    int p = 1;
    for(int i = 1; i <= q; i++){
        while(p<b[i].l){
            //printf("\\\\%d\n",p);
            update(p,nx[p]-1,a[p],1,n,1);
            //printf("---\n");
            p++;
        }
        //printf("==%d %d %d\n",b[i].id,b[i].l,b[i].r);
        //printf("--%d %d\n",i,ask(b[i].r,1,n,1));
        ans[b[i].id]=ask(b[i].r,1,n,1);
    }
    for(int i = 1; i <= q; i++){
        printf("%d\n",ans[i]);
    }
    return 0;        
}

/*
7 5
0 2 1 0 1 3 2
1 3
2 3
1 4
3 6
2 7
 */

 

posted @ 2019-07-07 23:16  wrjlinkkkkkk  阅读(233)  评论(0编辑  收藏  举报