权值线段树模板题

array
Time Limit: 1500ms Memory Limit: 256M Description
You are given an array . Initially, each element of the array is unique.
Moreover, there are  instructions. Each instruction is in one of the following two formats: 1. ,indicating to change the value of  to ; 2. ,indicating to ask the minimum value which is not equal to any  (  ) and not less than . Please print all results of the instructions in format .
Input
The first line of the input contains an integer , denoting the number of test cases. In each test case, there are two integers , in the first line, denoting the size of array  and the number of instructions.
In the second line, there are  distinct integers  ,denoting the array. For the following  lines, each line is of format  or . The parameters of each instruction are generated by such way : For instructions in format  , we defined  . (It is promised that )
For instructions in format  , we defined . (It is promised that  ) (Note that  means the bitwise XOR operator. ) Before the first instruction of each test case,  is equal to  .After each instruction in format ,  will be changed to the result of that instruction.
( ) Output
For each instruction in format , 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 [/hint]

#include <bits/stdc++.h>
#pragma GCC optimize(3)
using namespace std;
typedef int ll;
const int maxn=1e5+7;
const ll inf=1e9;
int n,m,str2[maxn];//str2是保存原本的值
struct inti{
    int data,poi;
}str[maxn];//保存原本的值之后排序,方便建立线段树
struct node{
    int l,r;
    int Maxr;
}arr[4*maxn];//线段树结构体数组
bool cmp(inti a,inti b){
    return a.data<b.data;
}
void build(int p,int l,int r){//建树
    arr[p].l=l,arr[p].r=r;
    if(l==r){
        arr[p].Maxr=str[l].poi;
        return;
    }
    int mid=(l+r)/2;
    build(p*2,l,mid);
    build(p*2+1,mid+1,r);
    arr[p].Maxr=max(arr[p*2].Maxr,arr[p*2+1].Maxr);//从下到上更新
}
void change(int p,int x){//把值为x的下标更新为n+1
    if(arr[p].l==arr[p].r){
        arr[p].Maxr=n+1;
        return;
    }
    int mid=(arr[p].l+arr[p].r)/2;
    if(x<=mid)change(p*2,x);
    else change(p*2+1,x);
    arr[p].Maxr=max(arr[p*2].Maxr,arr[p*2+1].Maxr);//从下到上更新最大区间下标
}
int ask(int p,int l,int r,int R){//询问l-r权值区间最小的且下标比R大的值,其实在这里r好像没用到,因为都是n+1
    if(arr[p].Maxr<=R)return n+1;
    if(arr[p].l==arr[p].r&&arr[p].l>=l){
        if(arr[p].Maxr>R)return arr[p].l;
        return n+1;
    }
    int mid=(arr[p].l+arr[p].r)/2;
    int val=n+1;//最大值为n+1
    if(l<=mid)val=min(val,ask(p*2,l,r,R));//取最小值
    if(r>mid)val=min(val,ask(p*2+1,l,r,R));//取最小值
    return val;
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--){
        scanf("%d %d",&n,&m);
        str[n+1].data=n+1,str[n+1].poi=n+1;
        for(int i=1;i<=n;++i)
            scanf("%d",&str[i].data),str[i].poi=i,str2[i]=str[i].data;
        sort(str+1,str+n+1,cmp);
        build(1,1,n+1);
        int id,a,b,lastans=0;
        while(m--){
            scanf("%d",&id);
            if(id==1){
                scanf("%d",&a);
                change(1,str2[a^lastans]);
            }
            else{
                scanf("%d %d",&a,&b);
                int r=a^lastans,k=b^lastans;
                int ans=ask(1,k,n+1,r);
                printf("%d\n",ans);
                lastans=ans;//更新lastans
            }
        }
    }
    return 0;
}

  

猜你喜欢

转载自www.cnblogs.com/lengsong/p/11404522.html
今日推荐