hdu 6703 权值线段树

Posted bxd123

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu 6703 权值线段树相关的知识,希望对你有一定的参考价值。

  题意:

给出一个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\\n",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\\n",lastans);
            
        
    
View Code

 

以上是关于hdu 6703 权值线段树的主要内容,如果未能解决你的问题,请参考以下文章

2019CCPC网络选拔赛 array(权值线段树)

[数据结构] 主席树初识(理论,代码待补)

主席树(区间第k小)

可持久化线段树--主席树

知识点 - 线段树 权值 树套树 二维 可持续

HDU 6464 /// 权值线段树