zoukankan      html  css  js  c++  java
  • 2019CCPC网络赛——array(权值线段树)

    题目链接http://acm.hdu.edu.cn/showproblem.php?pid=6703

    题目大意:

    给出一个n(n<1e5)个元素的数组A,A中所有元素都是不重复的[1,n]。

    有两种操作:

    1.将pos位置的元素+1e7

    2.查询不属于[1,r]中的最小的>=k的值。

    强制在线,上次计算结果和输入值xor得到区间。

    比赛的时候感觉这道题有点线段树的感觉,和前段时间多校训练一个题很像,想了40多分钟才理想清思路。

    解法:

      可以看出,执行1操作的时候加的数非常大,可以得出每次输出的答案在为1到n+1之间。可以将1-n的每个数在数组A中的位置记录下,存在线段树中,维护线段树区间最大值。

      当执行2操作时,只需要查询区间[k,n]中大于r的值即可,找出最小的数字,先搜索左子树,若无答案搜索右子树,若两侧均无解则答案为n+1。

      当执行1操作时,由于pos+1e7,因此之后的数组中不存在该数,将第pos位的数字在线段树中的值转换为inf即可。

      贴上自己比赛时打了40多分钟的代码

    #include<bits/stdc++.h>
    
    using namespace std;
    typedef long long ll;
    typedef long double ld;
    typedef unsigned long long ull;
    typedef pair <int,int> pii;
    #define rep(i,x,y) for(int i=x;i<y;i++)
    #define rept(i,x,y) for(int i=x;i<=y;i++)
    #define per(i,x,y) for(int i=x;i>=y;i--)
    #define pb push_back
    #define mp make_pair
    #define fi first
    #define se second
    #define de(x) cout<< #x<<" = "<<x<<endl
    #define dd(x) cout<< #x<<" = "<<x<<" "
    #define mes(a,b) memset(a,b,sizeof a)
    const int inf= 0x3f3f3f3f;
    int arrcy[100005],p[100005];
    class Tree
    {
        public:
            int l,r,val;
    }tree[400005];
    void build(int id,int l,int r);
    void change(int id,int x);
    void test();
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        int t;
        cin>>t;
        while(t--)
            test();
        return 0;
    }
    int find(int id,int r,int k);
    void test()
    {
        int n,q;
        int ans=0;
        cin>>n>>q;
        rept(i,1,n)
        {
            cin>>arrcy[i];
            p[arrcy[i]]=i;
        }
        build(1,1,n);
        rep(i,0,q)
        {
            int way;
            cin>>way;
            if(way==1)
            {
                int pos;
                cin>>pos;
                change(1,arrcy[ans^pos]);
            }
            else
            {
                int r,k;
                cin>>r>>k;
                r^=ans;
                k^=ans;
        //        cout<<"r="<<r<<" "<<"k="<<k<<endl;
                ans=find(1,r,k);
                if(ans==-1)
                    ans=max(n+1,k);
                cout<<ans<<endl;
            }
        }
    }
    void build(int id,int l,int r)
    {
        tree[id].l=l;
        tree[id].r=r;
        if(l==r)
        {
            tree[id].val=p[l];
            return ;
        }
        int mid=(l+r)/2;
        build(id*2,l,mid);
        build(id*2+1,mid+1,r);
        tree[id].val=max(tree[id*2].val,tree[id*2+1].val);
    }
    
    int find(int id,int r,int k)
    {
        if(tree[id].l==tree[id].r)
        {
            if(tree[id].val>r)
                return tree[id].l;
            else return -1;
        }
        int mid=(tree[id].l+tree[id].r)/2,ans=-1;
        if(mid>=k&&tree[id*2].val>r) ans=find(id*2,r,k);
        if(ans!=-1) return ans;
        else if(tree[id*2+1].r>=k&&tree[id*2+1].val>r) ans=find(id*2+1,r,k);
        return ans;
    }
    
    void change(int id,int x)//将x转换为inf
    {
        if(tree[id].l==tree[id].r)
        {
            tree[id].val=inf;
            return ;
        }
        if(x<=(tree[id].l+tree[id].r)/2) change(id*2,x);
        else change(id*2+1,x);
        tree[id].val=max(tree[id*2].val,tree[id*2+1].val);
    }
  • 相关阅读:
    【POJ 2259】Team Queue【队列】
    【POJ 2259】Team Queue【队列】
    【HDU 4699】Editor【栈】
    【HDU 4699】Editor【栈】
    【HDU 4699】Editor【栈】
    【POJ 2559】Largest Rectangle in a Histogram【栈】
    数据结构实验之栈八:栈的基本操作
    数据结构实验之栈八:栈的基本操作
    数据结构实验之栈七:出栈序列判定
    数据结构实验之栈七:出栈序列判定
  • 原文地址:https://www.cnblogs.com/FZUzyz/p/11498165.html
Copyright © 2011-2022 走看看