hdoj6703 2019 CCPC network trials 1002 array

The meaning of problems

description

You are given an array a1,a2,...,an(∀i∈[1,n],1≤ai≤n). Initially, each element of the array is **unique**. Moreover, there are m instructions. Each instruction is in one of the following two formats: 1. (1,pos),indicating to change the value of apos to apos+10,000,000; 2. (2,r,k),indicating to ask the minimum value which is **not equal** to any ai ( 1≤i≤r ) and **not less ** than k. Please print all results of the instructions in format 2.

input

The first line of the input contains an integer T(1≤T≤10), denoting the number of test cases. In each test case, there are two integers n(1≤n≤100,000),m(1≤m≤100,000) in the first line, denoting the size of array a and the number of instructions. In the second line, there are n distinct integers a1,a2,...,an (∀i∈[1,n],1≤ai≤n),denoting the array. For the following m lines, each line is of format (1,t1) or (2,t2,t3). The parameters of each instruction are generated by such way : For instructions in format 1 , we defined pos=t1⊕LastAns . (It is promised that 1≤pos≤n) For instructions in format 2 , we defined r=t2⊕LastAns,k=t3⊕LastAns. (It is promised that 1≤r≤n,1≤k≤n ) (Note that ⊕ means the bitwise XOR operator. ) Before the first instruction of each test case, LastAns is equal to 0 .After each instruction in format 2, LastAns will be changed to the result of that instruction. (∑n≤510,000,∑m≤510,000 )

analysis

Title, a total of two operations, one is the k-th digit +1000,0000, one is seeking a minimum, is not equal to ai (1 <= i <= r), and is not less than the number k.

Note that this number may not be present in the array

Because the number of different array, therefore, is not equal to ai (1 <= i <= r), is equivalent to this number may appear in the ai (r + 1 <= i <= n).
Why is it possible? Since the first operation because +1000,10000, that number will be making the first operation, in any case will not be repeated and ai (1000,0000 too much big than 51,0000).
Therefore, this problem, we can make the appropriate changes President tree, once for each ai [r + 1, n], no less than the minimum number k.
Because of this problem, array of 1-n of the n digits, so irrespective of the digital de-emphasis (UNIQUE), and the discretization problem.
In addition to the above two cases, there is a situation, we did not take into account, if k = n (XOR operation has been), then the answer is also possible that n + 1.
In summary, the answer is a total of three cases:

  • ai [r + 1, n] of a number (which can be solved by the President of the tree)
  • A first operation carried out a certain number (which will be digitally placed in a first set of operations)
  • n + 1

Three figures, for the minimum to

Code

#include <iostream>
#include <cstdio>
#include <set>
#include <algorithm>
int const maxn = 530000;
int const inf = 0x3f3f3f3f;
using namespace std;
int a[maxn], b[maxn];
int root[maxn << 5];//第几个版本的根节点编号
int lc[maxn << 5], rc[maxn << 5], sum[maxn << 5];
int sz;//节点个数
int n, m;

void build(int &rt, int l, int r) {
    rt = ++sz;
    if (l == r) return;
    int mid = (l + r) >> 1;
    build(lc[rt], l, mid);
    build(rc[rt], mid + 1, r);
}

int update(int id, int l, int r, int pos) {
    int _id = ++sz;
    lc[_id] = lc[id], rc[_id] = rc[id], sum[_id] = sum[id] + 1;
    if (l == r) return _id;
    int mid = (r + l) >> 1;
    if (pos <= mid)
        lc[_id] = update(lc[id], l, mid, pos);
    else
        rc[_id] = update(rc[id], mid + 1, r, pos);
    return _id;
}

//查询 不比k大的最小数字
int query(int p, int q, int l, int r, int k) {
    if (l == r) return l;
    int x1 = sum[lc[q]] - sum[lc[p]];
    int x2 = sum[rc[q]] - sum[rc[p]];
    int mid = (l + r) >> 1;
    int ans = inf;
    if (x1 > 0 && mid >= k)
        ans = query(lc[p], lc[q], l, mid, k);
    //这个if不能写为else,因为第一个if可能无法得到结果,返回inf
    if(ans == inf && x2 > 0 && r >= k)
        ans = query(rc[p], rc[q], mid + 1, r, k);
    return ans;
}


int main() {
    int T;
    scanf("%d", &T);
    while (T--) {
        while (~scanf("%d %d", &n, &m)) {
            sz = 0;
            set<int> s;
            int lastAns = 0;
            for (int i = 1; i <= n; i++) {
                scanf("%d", &a[i]);
                b[i] = a[i];
            }
            sort(b + 1, b + n + 1);
            build(root[0], 1, n);
            for (int i = 1; i <= n; i++) {
                int pos = lower_bound(b + 1, b + n + 1, a[i]) - b;
                root[i] = update(root[i - 1], 1, n, pos);
            }
            while (m--) {
                int l;
                scanf("%d", &l);
                if (l == 1) {
                    int pos = 1; // 随意初始化
                    scanf("%d", &pos);
                    pos ^= lastAns;
                    //cout << "pos = " << pos << endl;
                    s.insert(a[pos]);
                }
                else {
                    int l, k;
                    scanf("%d %d", &l, &k);
                    l ^= lastAns;
                    k ^= lastAns;
                    //cout << "l = " << l << "k = " << k << endl;
                    int ansPos = query(root[l - 1 + 1], root[n], 1, n, k);
                    lastAns = (ansPos == inf) ? inf : b[ansPos];
                    set<int>::iterator it = s.lower_bound(k);
                    //
                    if (it != s.end())  lastAns = min(lastAns, *it);
                    lastAns = min(lastAns, n + 1);
                    printf("%d\n", lastAns);
                }
            }
        }
    }
    return 0;

Guess you like

Origin www.cnblogs.com/woxiaosade/p/11422266.html