• 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);
    }
  • 相关阅读:
    js 日期2015/12/22/16/45替换2015-12-22 16:45格式
    正则匹配多行内容
    js fs read json 文件json字符串无法解析
    未能加载文件或程序集“Enyim.Caching”或它的某一个依赖项。未能验证强名称签名
    二叉树、多叉树子路径遍历
    p点到(a,b)点两所在直线的垂点坐标及p点是否在(a,b)两点所在直线上
    System.Net.Sockets.Socket SendAsync System.ObjectDisposedException: Cannot access a disposed object.
    一个误解: 单个服务器程序可承受最大连接数“理论”上是“65535”
    如何用 PyCharm 调试 scrapy 项目
    c或c++的网络库
  • 原文地址:https://www.cnblogs.com/FZUzyz/p/11498165.html
Copyright © 2020-2023  润新知