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 模板二逼平衡树(树套树)的主要内容,如果未能解决你的问题,请参考以下文章