hdu-6703 array(主席树+set)

主席树维护最小值

如果一个数被插入队列,相当于这个数无法被选 inf

如果一个数加1e7;相当于这个数又可以被选

实际维护+1e7的操作比较麻烦

直接用将+1e7的数字压入set中二分找>=k的最小的数在于查找的答案去min

#include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<set>
#include<map>
#include<vector>
#include<bitset>

#define inf 0x3f3f3f3f
#define mem(a,b) memset(a,b,sizeof(a))
#define ll long long
#define sd(x) scanf("%d",&(x))
#define sl(x) scanf("%lld",&(x))
#define slf(x) scanf("%lf",&(x))
#define scs(s) scanf("%s",s)
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
#define lowbit(x) x&(-x)
#define ls now<<1
#define rs now<<1|1
#define lson l,mid,ls
#define rson mid+1,r,rs
#define All L,R
using namespace std;

const int maxn=5e5+10;


struct Node{
    int l,r,s;
}tree[maxn*32];

int a[maxn];

int root[maxn],Min[maxn*32];

int n,m,tot=0,k=0;

int built(int l,int r)
{
    int mid=(l+r)>>1;
    int now=++k;
    if(l==r)
    {
        Min[now]=l;
        return now;
    }
    tree[now].l=built(l,mid);
    tree[now].r=built(mid+1,r);
    Min[now]=min(Min[tree[now].l],Min[tree[now].r]);
    return now;
}

int update(int pre,int p,int l,int r)
{
    int mid=(l+r)>>1;
    int now=++k;
    tree[now].l=tree[pre].l;
    tree[now].r=tree[pre].r;
    if(l==r)
    {
        Min[now]=1e9;
        return now;
    }
    if(p<=mid)
        tree[now].l=update(tree[pre].l,p,l,mid);
    else
        tree[now].r=update(tree[pre].r,p,mid+1,r);
    Min[now]=min(Min[tree[now].l],Min[tree[now].r]);
    return now;
}

int query(int now,int l,int r,int L,int R)
{
    int mid=(l+r)/2;
    if(l>=L&&r<=R){
        return Min[now];
    }
    int ans=1e9;
    if(L<=mid)ans=min(ans,query(tree[now].l,l,mid,L,R));
    if(R>mid)ans=min(ans,query(tree[now].r,mid+1,r,L,R));
    return ans;
}

int main()
{
    int t;
    int h=1e5+1;
    cin>>t;
    root[0]=built(1,h);
    while(t--)
    {
        int last=0;
        cin>>n>>m;
        for(int i=1;i<=n;i++)
        {
            cin>>a[i];
            root[i]=update(root[i-1],a[i],1,h);
        }
        set<int>s;
        while(m--)
        {
            int cmd,t1,t2,t3;
            sd(cmd);
            if(cmd==1)
            {
                sd(t1);
                t1^=last;
                s.insert(a[t1]);
            }
            else
            {
                sd(t2),sd(t3);
                t2^=last;
                t3^=last;
                int a1=query(root[t2],1,h,t3,h);
                int a2=1e9;
                auto it=s.lower_bound(t3);
                if(it!=s.end()) a2=*it;
                last=min(a1,a2);
                cout<<last<<"\n";
            }
        }
    }
    return 0;
}

 

posted @ 2019-08-29 10:54  Minun  阅读(185)  评论(0编辑  收藏  举报