BZOJ 3339 Rmq Problem

Posted on 2016-10-21 12:16  ziliuziliu  阅读(114)  评论(0编辑  收藏  举报

感谢http://hzwer.com/3032.html。

233333怎么全是抄黄学长题解。。。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 200050
#define inf 2000000000
using namespace std;
int n,m,a[maxn],sg[maxn],nxt[maxn],regis[maxn],tot=0,root,ls[maxn<<2],rs[maxn<<2],mn[maxn<<2],ans[maxn];
bool vis[maxn];
struct seg
{
    int l,r,id;    
}s[maxn];
bool cmp(seg x,seg y)
{
    return x.l<y.l;
}
void get_table()
{
    for (int i=1;i<=n;i++)
    {
        vis[a[i]]=true;
        for (int j=sg[i-1];;j++)
            if (!vis[j])
            {
                sg[i]=j;
                break;
            }
    }
    for (int i=n;i>=1;i--)
    {
        if (!regis[a[i]]) nxt[i]=n+1;
        else nxt[i]=regis[a[i]];
        regis[a[i]]=i;
    }
}
void build(int &now,int left,int right)
{
    now=++tot;mn[now]=inf;
    if (left==right) return;
    int mid=left+right>>1;
    build(ls[now],left,mid);
    build(rs[now],mid+1,right);
}
void modify(int now,int left,int right,int l,int r,int x)
{
    if (l>r) return;
    if ((left==l) && (right==r))
    {
        mn[now]=min(mn[now],x);
        return;
    }
    int mid=left+right>>1;
    if (r<=mid) modify(ls[now],left,mid,l,r,x);
    else if (l>=mid+1) modify(rs[now],mid+1,right,l,r,x);
    else
    {
        modify(ls[now],left,mid,l,mid,x);
        modify(rs[now],mid+1,right,mid+1,r,x);    
    }
}
int ask(int now,int left,int right,int x)
{
    if (left==right) return min(sg[left],mn[now]);
    int mid=left+right>>1;
    if (x<=mid) return min(mn[now],ask(ls[now],left,mid,x));
    else return min(mn[now],ask(rs[now],mid+1,right,x));
}
int main()
{
    scanf("%d%d",&n,&m);
    for (int i=1;i<=n;i++) scanf("%d",&a[i]);
    get_table();
    build(root,1,n);
    for (int i=1;i<=m;i++)
    {
        scanf("%d%d",&s[i].l,&s[i].r);
        s[i].id=i;
    }
    sort(s+1,s+m+1,cmp);int j=1;
    for (int i=1;i<=n;i++)
    {
        for (;j<=m;j++)
        {
            if (s[j].l!=i) break;
            ans[s[j].id]=ask(root,1,n,s[j].r);
        }
        if (i!=n) modify(root,1,n,i+1,nxt[i]-1,a[i]);
    }
    for (int i=1;i<=m;i++) printf("%d\n",ans[i]);
    return 0;
}