求调线段树套fhq(
查看原帖
求调线段树套fhq(
147401
koishi_offical楼主2021/3/19 20:50

怀疑是求前缀和后继求错了

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=5e4+10;
int n,m;
struct node
  {
      int l;
      int r;
      int val;
      int key;
      int siz;
  } tr[N<<7];
inline int read(){
    int x=0,f=1;
    char c=getchar();
    while(c<'0'||c>'9'){
        if(c=='-')f=-1;
        c=getchar();
    }
    while(c>='0'&&c<='9'){
        x=(x<<3)+(x<<1)+c-'0';
        c=getchar();
    }
    return x*f;
}
int root[N<<2],idx;
int new_node(int val)
  {
      int p=++idx;
      tr[p].val=val;
      tr[p].key=rand();
      tr[p].siz=1;
      tr[p].l=tr[p].r=0;
      return p;
  }
void update(int p)
  {
      tr[p].siz=tr[tr[p].l].siz+tr[tr[p].r].siz+1;
  }
void split_val(int now,int val,int &x,int &y)
   {
      if(!now) 
       {
           x=y=0;
           return;
       }
      if(tr[now].val<=val)
        {
            x=now;
            split_val(tr[now].r,val,tr[now].r,y);
        }
      else
        {
            y=now;
            split_val(tr[now].l,val,x,tr[now].l);
        }
      update(now);
  }
int merge(int x,int y)
  {
      if(!x||!y) return x+y;
      if(tr[x].key<tr[y].key)
        {
            tr[x].r=merge(tr[x].r,y);
            update(x);
            return x;
        }
      else
        {
            tr[y].l=merge(x,tr[y].l);
            update(y);
            return y;
        }
  }
int a[N],q[N];
void build(int k,int l,int r)
  {
       for(int i=l;i<=r;i++)
        {
            int tx,ty;
            split_val(root[k],a[i],tx,ty);
            root[k]=merge(merge(tx,new_node(a[i])),ty);
        }
      if(l!=r)
        {
             int mid=l+r>>1;
             build(k<<1,l,mid);
             build(k<<1|1,mid+1,r);
        }
  }
int got_rank(int k,int l,int r,int x,int y,int v)
  {
      if(l>=x&&r<=y)
        {
            int tx,ty;
            split_val(root[k],v-1,tx,ty);
            int ans=tr[tx].siz;
            root[k]=merge(tx,ty);
            return ans;
        }
      int mid=l+r>>1,sumans=0;
      if(x<=mid) sumans+=got_rank(k<<1,l,mid,x,y,v);
      if(y>mid) sumans+=got_rank(k<<1|1,mid+1,r,x,y,v);
      return sumans;
  }
int got_val(int k,int x,int y)
  {
      int l=0,r=1e8+1,mid,ans=0;
      while(l<r)
        {
            mid=l+r>>1;
            if(got_rank(1,1,n,x,y,mid)+1<=k)
              {
                  ans=mid;
                  l=mid+1;
              }
            else r=mid;
        }
      return ans;
  }
void change(int k,int l,int r,int p,int v)
  {
      int tx,ty,tz;
      split_val(root[k],a[p],tx,tz);
      split_val(tx,a[p]-1,tx,ty);
      ty=merge(tr[ty].l,tr[ty].r);
      root[k]=merge(merge(tx,ty),tz);
      split_val(root[k],v,tx,ty);
      root[k]=merge(merge(tx,new_node(v)),ty);
      if(l!=r)
        {
            int mid=l+r>>1;
            if(p<=mid) change(k<<1,l,mid,p,v);
            else change(k<<1|1,mid+1,r,p,v);
        }
  }
int got_pre(int k,int l,int r,int x,int y,int v)
  {
      if(l>=x&&r<=y)
        {
            int tx=0,ty=0,ans=-2147483647;
            split_val(root[k],v-1,tx,ty);
            int p=tx;
            if(!tx) return ans;
            while(tr[p].r) p=tr[p].r;
            ans=tr[p].val;
            root[k]=merge(tx,ty);
            return ans;
        }
      int mid=l+r>>1,ans=-2147483647;
      if(x<=mid) ans=max(ans,got_pre(k<<1,l,mid,x,y,v));
      if(y>mid)  ans=max(ans,got_pre(k<<1|1,mid+1,r,x,y,v));
      return ans;
  }
int got_nex(int k,int l,int r,int x,int y,int v)
  {
      if(l>=x&&r<=y)
        {
            int tx,ty=0,ans=2147483647;
            split_val(root[k],v,tx,ty);
            if(!ty) return ans;
            int p=ty;
            while(tr[p].l) p=tr[p].l;
            ans=tr[p].val;
            root[k]=merge(tx,ty);
            return ans;
        }
      int mid=l+r>>1,ans=2147483647;
      if(x<=mid) ans=min(ans,got_nex(k<<1,l,mid,x,y,v));
      if(y>mid) ans=min(ans,got_nex(k<<1|1,mid+1,r,x,y,v));
      return ans;
  }
signed main() {
    n=read(),m=read();
    for(int i=1;i<=n;i++)
      {
          a[i]=read();
          q[i]=a[i];
      }
    build(1,1,n);
    sort(q+1,q+n+1);
    while(m--)
      {
          int op,x,y,v;
          op=read();
          if(op==1)
            {
                x=read(),y=read(),v=read();
                cout<<got_rank(1,1,n,x,y,v)+1<<endl;
            }
          if(op==2)
            {
                x=read(),y=read(),v=read();
                cout<<got_val(v,x,y)<<endl;
            }
          if(op==3)
            {
                x=read(),v=read();
                change(1,1,n,x,v);
            }
          if(op==4)
            {
                x=read(),y=read(),v=read();
                cout<<got_pre(1,1,n,x,y,v)<<endl;
            }
          if(op==5)
            {
                x=read(),y=read(),v=read();
                cout<<got_nex(1,1,n,x,y,v)<<endl;
            }
      }
}
2021/3/19 20:50
加载中...