HDU6703 Array 【权值线段树+二分】

题目链接:HDU6703 Array

Array

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)
 

Problem 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 )

 Output

For each instruction in format 2, output the answer in one line.

 Sample Input

3
5 9
4 3 1 2 5 
2 1 1
2 2 2
2 6 7
2 1 3
2 6 3
2 0 4
1 5
2 3 7
2 4 3
10 6
1 2 4 6 3 5 9 10 7 8 
2 7 2
1 2
2 0 5
2 11 10
1 3
2 3 2
10 10
9 7 5 3 4 10 6 2 1 8 
1 10
2 8 9
1 12
2 15 15
1 12
2 1 3
1 9
1 12
2 2 2
1 9

Sample Output

1
5
2
2
5
6
1
6
7
3
11
10
11
4
8
11

Hint

note:
After the generation procedure ,the instructions of the first test case are :
2 1 1, in format 2 and r=1 , k=1
2 3 3, in format 2 and r=3 , k=3
2 3 2, in format 2 and r=3 , k=2
2 3 1, in format 2 and r=3 , k=1
2 4 1, in format 2 and r=4 , k=1
2 5 1, in format 2 and r=5 , k=1
1 3  , in format 1 and pos=3
2 5 1, in format 2 and r=5 , k=1
2 5 2, in format 2 and r=5 , k=2

the instructions of the second test case are :
2 7 2, in format 2 and r=7 , k=2
1 5  , in format 1 and pos=5
2 7 2, in format 2 and r=7 , k=2
2 8 9, in format 2 and r=8 , k=9
1 8  , in format 1 and pos=8
2 8 9, in format 2 and r=8 , k=9

the instructions of the third test case are :
1 10   , in format 1 and pos=10
2 8 9  , in format 2 and r=8 , k=9
1 7    , in format 1 and pos=7
2 4 4  , in format 2 and r=4 , k=4
1 8    , in format 1 and pos=8
2 5 7  , in format 2 and r=5 , k=7
1 1    , in format 1 and pos=1
1 4    , in format 1 and pos=4
2 10 10, in format 2 and r=10 , k=10
1 2    , in format 1 and pos=2

 

 题意:找出[k,n+1]之间坐标大于r的最小值

分析:权值线段树维护区间坐标最大值,update指向n+1,query求值,find二分剪枝的思想,左边找不到去右边

#include
#define lson rt<<1
#define rson rt<<1|1
#define INF 0x3f3f3f3f
using namespace std;
const int maxn=2e5+100;
int n,m,ans;
int a[maxn],pos[maxn];
struct node{int l,r,p;} tree[maxn<<2];
void pushup(int rt) {tree[rt].p=max(tree[lson].p,tree[rson].p);}
void build(int rt,int l,int r)
{
    tree[rt].l=l;tree[rt].r=r;
    if(l==r) 
    {
        tree[rt].p=pos[l];
        return ;
    }
    int mid=(l+r)>>1;
    build(lson,l,mid);build(rson,mid+1,r);
    pushup(rt);
}
void update(int rt,int num)
{
    if(numtree[rt].r) return ;
    if(tree[rt].l==tree[rt].r) 
    {
        tree[rt].p=n+1;
        return ;
    } 
    update(lson,num);update(rson,num);
    pushup(rt);
}
void find(int rt,int rr)
{
    if(tree[lson].p>rr) find(lson,rr);
    else if(tree[rson].p>rr) find(rson,rr);
    if(tree[rt].p>rr && tree[rt].l==tree[rt].r) ans=min(ans,tree[rt].l);
}
void query(int rt,int ql,int qr,int rr)
{
    if(ql<=tree[rt].l && tree[rt].r<=qr)
    {
        find(rt,rr);
        return;
    }
    int mid=(tree[rt].l+tree[rt].r)>>1;
    if(ql<=mid) query(lson,ql,qr,rr);
    if(qr>mid) query(rson,ql,qr,rr);
}
void rua()
{
    scanf("%d%d",&n,&m);
    for (int i=1;i<=n;i++) scanf("%d",&a[i]),pos[a[i]]=i;
    pos[n+1]=n+1;
    build(1,1,n+1);
    ans=0;
    while (m--)
    {
        int op;scanf("%d",&op);
        if(op==1) 
        {
            int kk;scanf("%d",&kk);kk^=ans;
            update(1,a[kk]);
        }
        else
        {
            int r,k;scanf("%d%d",&r,&k);r^=ans;k^=ans;
            ans=INF;
            query(1,k,n+1,r);
            printf("%d\n",ans);
        }
    }
    return ;
}
int main()
{
    int t;scanf("%d",&t);
    while(t--) rua();
    return 0;
}

 

你可能感兴趣的:(数据结构,线段树,ACM/CCPC)