P3380 模板二逼平衡树(树套树)

Posted shxnb666

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P3380 模板二逼平衡树(树套树)相关的知识,希望对你有一定的参考价值。

题面

https://www.luogu.org/problem/P3380

题解

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<vector>
#define ri register int
using namespace std;
struct node
  vector<int> a;
  void insert(int x)
    a.insert(upper_bound(a.begin(),a.end(),x),x);
  
  void change(int old,int now) 
    a.erase(lower_bound(a.begin(),a.end(),old));
    a.insert(upper_bound(a.begin(),a.end(),now),now);
  
  int find(int now)
    if ((*a.begin())>=now) return 0;
    return lower_bound(a.begin(),a.end(),now)-a.begin();
  
 ff[50050];
int a[50050];
int n,m;

int lowbit(int x)
  return x&(-x);


int findbyrank(int l,int r,int k)
  int lb=-1e8,rb=1e8,mid,ans=-1;
  while (lb<=rb) 
    mid=(lb+rb)/2;
    int s1=0,s2=0;
    for (ri j=r;j>=1;j-=lowbit(j)) s1+=ff[j].find(mid);
    for (ri j=l-1;j>=1;j-=lowbit(j)) s2+=ff[j].find(mid);
    if (s1-s2+1<=k) lb=mid+1,ans=mid; else rb=mid-1;
  
  return ans;


int findpre(int l,int r,int k)
  int ans=-2147483647;
  for (ri i=r;i>=l;) if (i-lowbit(i)+1>=l) 
    if ((*ff[i].a.begin())>=k) i-=lowbit(i); continue;
    else ans=max(*(--lower_bound(ff[i].a.begin(),ff[i].a.end(),k)),ans);
    i-=lowbit(i);
  
  else 
    if (a[i]<k) ans=max(a[i],ans);
    i--;
  
  return ans;


int findsuc(int l,int r,int k)
  int ans=2147483647;
  for (ri i=r;i>=l;) if (i-lowbit(i)+1>=l) 
    if (ff[i].a[ff[i].a.size()-1]<=k) i-=lowbit(i);continue;
        else ans=min(*(upper_bound(ff[i].a.begin(),ff[i].a.end(),k)),ans);
    i-=lowbit(i);
  
  else 
    if (a[i]>k) ans=min(a[i],ans);
    i--;
  
  return ans;


int main() 
  int x,opt,l,r,k,pos;
  scanf("%d %d",&n,&m);
  for (ri i=1;i<=n;i++) 
    scanf("%d",&x);
    a[i]=x;
    for (ri j=i;j<=n;j+=lowbit(j)) ff[j].insert(x);
  
  for (ri i=1;i<=m;i++) 
    scanf("%d",&opt);
    if (opt==1) 
      scanf("%d %d %d",&l,&r,&k);
      int s1=0,s2=0;
      for (ri j=r;j>=1;j-=lowbit(j)) s1+=ff[j].find(k);
      for (ri j=l-1;j>=1;j-=lowbit(j)) s2+=ff[j].find(k);
      printf("%d\n",s1-s2+1);
    
    if (opt==2) 
      scanf("%d %d %d",&l,&r,&k);
      printf("%d\n",findbyrank(l,r,k));
    
    if (opt==3) 
      scanf("%d %d",&pos,&k);
      for (ri j=pos;j<=n;j+=lowbit(j)) ff[j].change(a[pos],k);
      a[pos]=k;
    
    if (opt==4) 
      scanf("%d %d %d",&l,&r,&k);
      printf("%d\n",findpre(l,r,k));
    
    if (opt==5) 
      scanf("%d %d %d",&l,&r,&k);
      printf("%d\n",findsuc(l,r,k));
    
  

 

以上是关于P3380 模板二逼平衡树(树套树)的主要内容,如果未能解决你的问题,请参考以下文章

P3380 模板二逼平衡树(树套树)

洛谷P3380 模板二逼平衡树(树套树,树状数组,线段树)

「luogu3380」模板二逼平衡树(树套树)

模板二逼平衡树(树套树)

luogu3380 模板二逼平衡树(树套树)

二逼平衡树(树套树)