HDU6703 array(线段树)

首先我们观察到a数组是一个排列,并且k也是在1-n之间,说明我们的答案一定是不大于n+1

又因为第一种操作直接加了1e7,因此我们相当于将这个数剔除,也就是将这个数作为可选范围内。

我们要求的是大于k的数,并且不能与1-r之间的答案相同。

那么我们就要直接从线段树上k-n找答案。

因此我们只需要维护一个区间下标最大值即可,只要区间每个数对应的坐标大于给定的r,那么就存在答案

对于第一种操作,只需要修改当前位置的坐标为n+1,表示这个点可以作为可选范围。

如果1-n没有答案,那么答案就是n+1

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+10;
int n,m;
int a[N];
int b[N];
struct node{
    int l,r;
    int cnt;
}tr[N<<2];
void pushup(int u){
    tr[u].cnt=max(tr[u<<1].cnt,tr[u<<1|1].cnt);
}
void build(int u,int l,int r){
    if(l==r){
        tr[u]={l,l,b[l]};
    }
    else{
        tr[u]={l,r,0};
        int mid=l+r>>1;
        build(u<<1,l,mid);
        build(u<<1|1,mid+1,r);
        pushup(u);
    }
}
set<int> s;
void modify(int u,int l){
    if(tr[u].l==tr[u].r){
        tr[u].cnt=n+1;
        return ;
    }
    int mid=tr[u].l+tr[u].r>>1;
    if(l<=mid)
        modify(u<<1,l);
    else
        modify(u<<1|1,l);
    pushup(u);
}
int query(int u,int l,int r,int x){
    if(tr[u].l >=l && tr[u].r <= r){
        if(tr[u].l == tr[u].r){
            if(tr[u].cnt>x)
                return tr[u].l;
            return n+1;
        }
        if(tr[u<<1].cnt>x)return query(u<<1,l,r,x);
        if(tr[u<<1|1].cnt>x)return query(u<<1|1,l,r,x);
        return n+1;
    }
    int mid=tr[u].l+tr[u].r >> 1;
    int res=n+1;
    if(mid>=l){
        res=query(u<<1,l,r,x);
    }
    if(mid < r){
        res=min(res,query(u<<1|1,l,r,x));
    }
    return res;
}
int main(){
    ios::sync_with_stdio(false);
    int t;
    cin>>t;
    while(t--){
        cin>>n>>m;
        int i;
        for(i=1;i<=n;i++) b[i]=0;
        for(i=1;i<=n;i++){
            cin>>a[i];
            b[a[i]]=i;
        }
        build(1,1,n);
        int last=0;
        while(m--){
            int opt,x,y;
            cin>>opt;
            if(opt==1){
                cin>>x;
                x^=last;
                modify(1,a[x]);
            }
            else{
                cin>>x>>y;
                x^=last,y^=last;
                cout<<(last=query(1,y,n,x))<<endl;
            }
        }
    }
}
View Code
没有人不辛苦,只有人不喊疼
原文地址:https://www.cnblogs.com/ctyakwf/p/13676343.html