zoukankan      html  css  js  c++  java
  • 权值线段树模板题

    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){//询问l-r权值区间最小的且下标比R大的值,其实在这里r好像没用到,因为都是n+1
        if(arr[p].l==arr[p].r&&arr[p].l>=l)
            return arr[p].l;
        int mid=(arr[p].l+arr[p].r)/2;
        int val=n+1;//最大值为n+1
        if(mid>=l&&arr[p*2].Maxr>R)val=min(val,ask(p*2,l,R));//取最小值,mid>=l属于优化剪枝
        if(mid<=n+1&&val==n+1&&arr[p*2+1].Maxr>R)val=min(val,ask(p*2+1,l,R));//取最小值,val==n+1是为了判断左
    //区间是否存在比n+1更小的值,如果存在的话肯定比右区间优,当然也就没有必要再进入右区间,mid<=n+1也属于一种剪枝
        return val;
    }
    template<class T>
    inline void read(T&x){
        T ans=0,f=1;
        char ch=getchar();
        while(ch>'9'||ch<'0'){
            if(ch=='-')f=-1;
            ch=getchar();
        }
        while(ch<='9'&&ch>='0')
            ans=ans*10+ch-'0',ch=getchar();
        x=ans*f;
    }
    template<class T>
    inline void prin(T x){
        if(x>9)prin(x/10);
        putchar(x%10+'0');//无回车
    }
    int main()
    {
        int t;
        read(t);
        while(t--){
            read(n);
            read(m);
            str[n+1].data=n+1,str[n+1].poi=n+1;
            for(register int i=1;i<=n;++i){
                read(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--){
                read(id);
                read(a);
                if(id==1)
                    change(1,str2[a^lastans]);
                else{
                    read(b);
                    int ans=ask(1,b^lastans,a^lastans);
                    prin(ans);
                    putchar('
    ');
                    lastans=ans;//更新lastans
                }
            }
        }
        return 0;
    }
    

      

     

     

  • 相关阅读:
    table固定头部,tbody内容滚动
    js 中json遍历 添加 修改 类型转换
    SEO优化
    JS对字符串的操作,截取
    移动端 去掉滚动栏
    JS 引擎的执行机制
    Uncaught SyntaxError: Unexpected token ILLEGAL
    利用css 画各种三角形
    js文本公告滚动展示,图片轮播....
    js判断手指的上滑,下滑,左滑,右滑,事件监听
  • 原文地址:https://www.cnblogs.com/lengsong/p/11404522.html
Copyright © 2011-2022 走看看