hdu 6703 array

思路:在给的数组上建立主席树,改一下查询,查询L到R之间第一个大于等于k的数,再设一个set,把去掉的数放到set中,查询完主席树找set中最接近k的数,答案就是取上面两个数中的最小值

#include 
#define eps 1e-14
#define pi acos(-1)
#define ll long long
#define RD T*(rand()*2-RAND_MAX)
#define Drand (long double)rand()/RAND_MAX
#define LINF 0x7f7f7f7f7f7f7f7f
#define INF 0x3f3f3f3f
using namespace std;
const int maxn=1e5+100;
const long long mod=1e18;
ll gcd(ll a,ll b){
     return b?gcd(b,a%b):a;}

int tot=0;
int a[maxn],L[maxn*21],R[maxn*21],sum[maxn*21],T[maxn];
int n,m;

void build(int l,int r,int &rt)
{
     
    rt=++tot;
    sum[rt]=0;
    if(l==r)return ;
    int mid=(l+r)>>1;
    build(l,mid,L[rt]);
    build(mid+1,r,R[rt]);
}

void update(int l,int r,int &rt,int pre,int x)
{
     
    rt=++tot;
    L[rt]=L[pre];
    R[rt]=R[pre];
    sum[rt]=sum[pre]+1;
    if(l==r)return;
    int mid=(l+r)>>1;
    if(x<=mid)update(l,mid,L[rt],L[pre],x);
    else update(mid+1,r,R[rt],R[pre],x);
}

int query(int l,int r,int tl,int tr,int k)
{
     
    if(l==r)return l>=k ? l : n+1 ;
    int mid=(l+r)>>1;
    int ans=n+1;
    int resl=sum[ L[tr] ]-sum[ L[tl] ];
    int resr=sum[ R[tr] ]-sum[ R[tl] ];
    if(resr+resl==0)return n+1;
    if(resl>0 && k<=mid){
     
        ans=query(l,mid,L[tl],L[tr],k);
    }
    if(ans!=n+1)return ans;
    if(resr>0){
     
        ans=query(mid+1,r,R[tl],R[tr],k);
    }
    return ans;
}

inline int read()
{
     
    int num = 0, flag = 1;
    char c;
    c = getchar();
    while(!(('0' <= c && c <= '9') || c == '-')) c = getchar();
    if(c == '-'){
     
        flag = -1; c = getchar();
    }
    while('0' <= c && c <= '9'){
     
        num = num * 10 + c - '0';
        c = getchar();
    }
    return num * flag;
}

int main() {
     
//    freopen("in.txt", "r", stdin);
//    freopen("out.txt", "w", stdout);
    int t;
    scanf("%d",&t);
    while(t--){
     
        n=read();
        m=read();
        tot=0;
//        build(1,n+1,T[0]);
        set<int>s;
        for(int i=1;i<=n;i++){
     
            a[i]=read();
            update(1,n+1,T[i],T[i-1],a[i]);
        }
        update(1,n+1,T[n+1],T[n],n+1);
        int ans=0;
        while(m--){
     
            int b;
            b=read();
            if(b==1){
     
                int pos=read();
                pos^=ans;
                s.insert(a[pos]);
            }
            else{
     
                int r=read(),k=read();
                r^=ans;k^=ans;
                ans=query(1,n+1,T[r],T[n+1],k);
                auto ans1=s.lower_bound(k);
                if(ans1!=s.end())ans=min(ans,*ans1);
                printf("%d\n",ans);
            }
        }
    }
    return 0;
}

你可能感兴趣的:(acm,主席树)