题面
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));
}
}
}