HDU-6703 array (segment tree)

The meaning of problems

A permutation of length n A, \ (\ FORALL I \ in [. 1, n],. 1 \ Le a_i \ Le n \) , m operations, each operation:

  1. (1, pos), the \ (a_ {pos} \) becomes \ (a_ {pos} + 10000000 \)
  2. (2, r, k), to find a minimum value of x, such that \ (\ forall i \ in [ 1, r], x \ neq a_i, x \ ge k \)

data range:

\ (1 \ n \ 100000.1 the \ m \ the 100000.1 \ r \ n, 1 \ k \ n \)

analysis

  1. Each number range was observed, in \ ([1, n-] \) between, and also the range of k \ ([1, n-] \) between, it will in the final answer \ ([1 ,) n + 1] \ between.

  2. 1 will operate a digital \ (a_i \) plus 1e7, and this has far exceeded the number of n and k, so it represents \ (a_i \) has been deleted from the original sequence.

  3. May be known by the first, the only answer to the query in each [k, + 1 n], the number in the sequence and only in [1, n-] (1 subjected delete operation, no consideration) . So we can have every query sequence does not appear in the \ ([k, n] \ ) numbers, and their index of greater than r. If a previously deleted or number \ (X \) , then put the index n becomes larger than it, so that for \ (k \ le x \) case, \ (X \) corresponding to the index are It is greater than \ (R & lt \) (i.e., the answer as a candidate x)

How to maintain what queries needed? Weight segment tree maintenance interval of the maximum weight index

  1. For an operation, directly from a single point becomes the subscript n + 1
  2. For operation 2, to be the interval [k, n] of the node comprises, for these nodes, if the maximum index left node is greater than r, then the recursive left node, or to see a right node, if not, returns n + 1 (on behalf of the answer candidate is n + 1). While the end of the recursion, to see whether the single point of maintenance of the index is greater than r, If so, it returns the weight of a single point, otherwise n + 1.
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5+10;
const int inf = 0x3f3f3f3f;
int a[N],b[N];
struct SegTree{
    int l,r,id;
}t[4*N];
int n,m;
void build(int p,int l,int r){
    t[p].l = l;t[p].r = r;
    if(l == r){
        t[p].id = b[l];
        return;
    }
    int mid = l + r >> 1;
    build(p*2,l,mid);
    build(p*2+1,mid+1,r);
    t[p].id = max(t[p*2].id,t[p*2+1].id);
}
void change(int p,int x){
    if(t[p].l == t[p].r && t[p].l == x){
        t[p].id = n+1;return;//删除该数,将维护的下标变为n+1
    }
    int mid = t[p].l + t[p].r >> 1;
    if(x <= mid)change(p*2,x);
    else if(x > mid)change(p*2+1,x);
    t[p].id = max(t[p*2].id,t[p*2+1].id);
}
int query(int p,int l,int r,int x){
    if(t[p].l >= l && t[p].r <= r){//找到被[k,n]完全包含的结点
        if(t[p].l == t[p].r){
            if(t[p].id > x)
                return t[p].l;
            return n + 1;
        }
        if(t[p*2].id > x)return query(p*2,l,r,x);
        if(t[p*2+1].id > x)return query(p*2+1,l,r,x);
        return n + 1;
    }
    int mid = t[p].l + t[p].r >> 1;
    int res = n+1;
    if(mid >= l){
        res = query(p*2,l,r,x);
    }
    if(mid < r){
        res = min(res, query(p*2+1,l,r,x));
    }
    return res;
}
int main(){
    int T;scanf("%d",&T);
    while(T--){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)b[i] = 0;
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
            b[a[i]] = i;//因为时排列,每个a[i]都不一样
        }
        build(1,1,n);
        int res = 0;
        while(m--){
            int op,x,y;
            scanf("%d%d",&op,&x);
            if(op == 1){
                x ^= res;
                change(1,a[x]);
            }
            else{
                scanf("%d",&y);x^=res;y^=res;
                res = query(1,y,n,x);
                printf("%d\n",res);
            }
        }
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/1625--H/p/11404011.html