hdu 6703 array

思路:在給的數組上建立主席樹,改一下查詢,查詢L到R之間第一個大於等於k的數,再設一個set,把去掉的數放到set中,查詢完主席樹找set中最接近k的數,答案就是取上面兩個數中的最小值

#include <bits/stdc++.h>
#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;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章