欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【JZOJ5710】Mex

程序员文章站 2024-02-13 23:09:04
...

problem

Description

在组合游戏中计算状态的 SG 值时,我们常常会遇到 mex 函数。mex(S) 的值为集合 S 中没有出现过的最小自然数。例如,mex({1,2}) = 0、mex({0,1,2,3}) = 4。
给定长度为 n 的序列 a。现有 m 次询问,每次给定 l 和 r,询问区间 [l,r] 的数构成的集合的 mex 值。

Input

输入数据的第一行包含三个整数 n、m 和 t,其中 t 为 0 或者 1,表示数据类型。
接下来一行,包含 n 个非负整数,为序列 a。
接下来 m 行,每行描述一个询问。第 i 行包含两个正整数 l 和 r,代表第 i 次询问的区间的左右端点。如果 t = 1,则询问进行了加密,从第二个询问开始,读入的 l 和 r 异或前一次询问的答案才是真正的询问左右端点。

Output

对于每个询问,输出一行,代表询问区间的 mex 值。

Sample Input

5 4 0
2 1 0 2 1
3 3
2 3
2 4
1 2

Sample Output

1
2
3
0

Data Constraint

【JZOJ5710】Mex


analysis

  • 主席树……

  • 这特么不还是求mex

  • 线段树本来就是在线,加个强制在线有意义么


code

#include<bits/stdc++.h>
#define MAXN 200001
#define INF 1000000007
#define fo(i,a,b) for (int i=a;i<=b;i++)

using namespace std;

int lson[MAXN*30],rson[MAXN*30],mn[MAXN*30];
int root[MAXN];
int n,m,type,tot,size;

int read()
{
    int x=0,f=1;
    char ch=getchar();
    while (ch<'0' || '9'<ch)
    {
        if (ch=='-')f=-1;
        ch=getchar();   
    }
    while ('0'<=ch && ch<='9')
    {
        x=x*10+ch-'0';
        ch=getchar();
    }
    return x*f;
}

void update(int &t,int old,int l,int r,int x,int y)
{
    t=++tot;
    lson[t]=lson[old],rson[t]=rson[old],mn[t]=mn[old];
    if (l==r)
    {
        mn[t]=y;
        return;
    }
    int mid=(l+r)/2;
    if (x<=mid)update(lson[t],lson[old],l,mid,x,y);
    else update(rson[t],rson[old],mid+1,r,x,y);
    mn[t]=min(mn[lson[t]],mn[rson[t]]);
}

int query(int t,int l,int r,int x)
{
    if (l==r)return l;
    int mid=(l+r)/2;
    if (mn[lson[t]]<x)return query(lson[t],l,mid,x);
    else return query(rson[t],mid+1,r,x);
}

int main()
{
    freopen("mex.in","r",stdin);
    freopen("mex.out","w",stdout);
    //freopen("readin.txt","r",stdin);
    n=read(),m=read(),type=read();
    fo(i,1,n)
    {
        int x=read();
        update(root[i],root[i-1],1,n+1,x+1,i);
    }
    while (m--)
    {
        int l=read(),r=read();
        if (type)l^=size,r^=size;
        printf("%d\n",size=query(root[r],1,n+1,l)-1);
    }
    return 0;
}