码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2019-08-29 00:02:56      阅读:77      评论:0      收藏:0      [点我收藏+]

标签:find   tps   cto   def   names   amp   lse   pac   fine   

题面

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 【模板】二逼平衡树(树套树)

标签:find   tps   cto   def   names   amp   lse   pac   fine   

原文地址:https://www.cnblogs.com/shxnb666/p/11427248.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!