zoukankan      html  css  js  c++  java
  • hdu 6703 权值线段树 or 主席树

      题意:

    给出一个1-n的全排列   a

    操作1:修改a[pos] 为 a[pos]+1000000

    操作2: 问k的所有后继中(包括k) 最小的 且与a[1]-a[r]均不相等的数是多少

    n<=1e5   

    #include<bits/stdc++.h>
    using namespace std;
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i>=(b);--i)
    #define ll long long
    #define see(x) (cerr<<(#x)<<'='<<(x)<<endl)
    #define inf 0x3f3f3f3f
    #define CLR(A,v)  memset(A,v,sizeof A)
    /////////////////////////////////////
    const int N=2e6+10;
    int maxx[N<<2],position[N];
    void up(int pos)
    {
        maxx[pos]=max(maxx[pos<<1],maxx[pos<<1|1]);
    }
    void build(int l,int r,int pos)
    {
        if(l==r){maxx[pos]=position[l];return ;}
        int m=(l+r)>>1;
        build(l,m,pos<<1);build(m+1,r,pos<<1|1);up(pos);
    }
    void upnode(int x,int l,int r,int pos)
    {
        if(l==r){maxx[pos]=inf;return ;}
        int m=(l+r)>>1;
        if(x<=m)upnode(x,l,m,pos<<1);
        else upnode(x,m+1,r,pos<<1|1);
        up(pos);
    }
    int query(int x,int L,int R,int l,int r,int pos)
    {
       if(l==r)
       {
           if(maxx[pos]>x)return l;
           else return inf;
       }
       int m=(l+r)>>1;int ans=inf;
       if(L<=m&&maxx[pos<<1]>x)ans=min(ans,query(x,L,R,l,m,pos<<1));
       if(ans!=inf)return ans;
       if(R>m&&maxx[pos<<1|1]>x)ans=min(ans,query(x,L,R,m+1,r,pos<<1|1));
       return ans;
    }
    int n,m,t1,t2,t3,lastans,f[N];
    int main()
    {
        int cas;cin>>cas;
        while(cas--)
        {
            scanf("%d%d",&n,&m);int x;
            rep(i,1,n)
            scanf("%d",&x),position[x]=i,f[i]=x;
            position[n+1]=inf;
            build(1,n+1,1);lastans=0;
            while(m--)
            {
                int a,b,c;scanf("%d",&a);
                if(a==1)
                {
                    scanf("%d",&b);b^=lastans;
                    upnode(f[b],1,n+1,1);
                }
                else
                {
                    scanf("%d%d",&b,&c);b^=lastans;c^=lastans;
                    lastans=query(b,c,n+1,1,n+1,1);
                    printf("%d
    ",lastans);
                }
            }
        }
        return 0;
    }
    View Code

    也可以用主席树来写

    #include<bits/stdc++.h>
    using namespace std;
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i>=(b);--i)
    #define ll long long
    #define see(x) (cerr<<(#x)<<'='<<(x)<<endl)
    #define inf 0x3f3f3f3f
    #define CLR(A,v)  memset(A,v,sizeof A)
    /////////////////////////////////////
    const int N=1e5+100;
    
    int T[N],lson[N<<5],rson[N<<5],ncnt,minn[N<<5];
    
    void build(int l,int r,int &pos)
    {
        pos=++ncnt;
        if(l==r){minn[pos]=l;return ;}
        int m=(l+r)>>1;
        build(l,m,lson[pos]);
        build(m+1,r,rson[pos]);
        minn[pos]=min(minn[lson[pos]],minn[rson[pos]]);
    }
    
    void up(int x,int l,int r,int pre,int &pos)
    {
        pos=++ncnt;
        lson[pos]=lson[pre];rson[pos]=rson[pre];
        if(l==r){minn[pos]=1e9;return ;}
        int m=(l+r)>>1;
        if(x<=m)up(x,l,m,lson[pre],lson[pos]);
        else up(x,m+1,r,rson[pre],rson[pos]);
        minn[pos]=min(minn[lson[pos]],minn[rson[pos]]);
    }
    
    int qsum(int L,int R,int l,int r,int pos)
    {
        int ans=1e9;
        if(L<=l&&r<=R)return minn[pos];
        int m=(l+r)>>1;
        if(L<=m)ans=min(ans,qsum(L,R,l,m,lson[pos]));
        if(R>m)ans=min(ans,qsum(L,R,m+1,r,rson[pos]));
        return ans;
    }
    
    set<int>s;int a[N];
    int main()
    {
    
        int cas;cin>>cas;
        while(cas--)
        {
            s.clear();
            ncnt=0;
            build(1,N,T[0]);
            int n,q,b,c,m,lastans=0,r,k,op;
            scanf("%d%d",&n,&m);
            rep(i,1,n)
            {
                scanf("%d",&a[i]);up(a[i],1,N,T[i-1],T[i]);
            }
            while(m--)
            {
                scanf("%d",&op);
                if(op==1)
                {
                    scanf("%d",&r);r^=lastans;
                    s.insert(a[r]);
                }
                else
                {
                    scanf("%d%d",&r,&k);r^=lastans;k^=lastans;
                    int ans=1e9;
                    auto it=s.lower_bound(k);
                    if(it!=s.end())
                    ans=min(ans,*it);
    
                    lastans=min(ans,qsum(k,N,1,N,T[r]));
    
                    printf("%d
    ",lastans);
                }
            }
        }
    }
    View Code
  • 相关阅读:
    2020年秋招三星面试题
    物联网金融和互联网金融的区别与联系
    数据库事务的4种隔离级别
    Access-cookie之sqlmap注入
    SDL-软件安全开发周期流程
    图片马的制作
    ssrf内网端口爆破扫描
    逻辑漏洞_验证码绕过_密码找回漏洞
    平行越权与垂直越权
    xff注入
  • 原文地址:https://www.cnblogs.com/bxd123/p/11408376.html
Copyright © 2011-2022 走看看