当 n>300 的时候会炸,不知道为啥。
#include<bits/stdc++.h>
#define EL out[wz++]='\n'
#define SP out[wz++]=' '
#define Yes out[wz++]='Y',out[wz++]='e',out[wz++]='s'
#define YES out[wz++]='Y',out[wz++]='E',out[wz++]='S'
#define No out[wz++]='N',out[wz++]='o'
#define NO out[wz++]='N',out[wz++]='O'
using namespace std;
char ibuf[900<<20],*re,out[900<<20];
int wz;
inline int read()
{
register int u=0,op=1;
while(*re<48||*re>57)
{
if(*re=='-')op=-1;
re++;
}
while(*re>=48&&*re<=57)
u=u*10+*re++-48;
return u*op;
}
inline long long readll()
{
register long long u=0,op=1;
while(*re<48||*re>57)
{
if(*re=='-')op=-1;
re++;
}
while(*re>=48&&*re<=57)
u=u*10+*re++-48;
return u*op;
}
void print(long long x)
{
if(x<0){out[wz++]='-';x=-x;}
if(x>9)print(x/10);
out[wz++]=x%10+'0';
}
void print(int x)
{
if(x<0){out[wz++]='-';x=-x;}
if(x>9)print(x/10);
out[wz++]=x%10+'0';
}
void print(string s)
{
for(int i=0;i<s.size();i++)out[wz++]=s[i];
}
void print(char* s)
{
for(int i=0;s[i]!='\0';i++)out[wz++]=s[i];
}
int n,l[800],r[800],a[500008],size,q,belong[500008],num,blk[500008],bl[800];
void blk_sort(int x){sort(blk+l[x],blk+r[x]+1);}
void reset(int x)
{
for(int i=l[x];i<=r[x];i++)
{
blk[i]=a[i];
}
blk_sort(x);
}
int htk(int l1,int r1,int c)
{
int ans=0;
int a1=belong[l1],b=belong[r1];
if(a1==b)
{
for(int i=l1;i<=r1;i++)ans+=(a[i]+bl[a1]<=c);
return ans;
}
for(int i=l1;i<=r[a1];i++)ans+=(a[i]+bl[a1]<=c);
for(int i=l[b];i<=r1;i++)ans+=(a[i]+bl[b]<=c);
for(int i=a1+1;i<b;i++)ans+=upper_bound(blk+l[i],blk+r[i]+1,c-bl[i])-(blk+l[i]);
return ans;
}
int kth(int l1,int r1,int k)
{
int l=-20000,r=20000,ans=-1;
while(l<=r)
{
int mid=(l+r)/2,v=htk(l1,r1,mid);
if(v<k)l=mid+1;
else
{
r=mid-1;
ans=mid;
}
}
return ans;
}
int main()
{
fread(re=ibuf,1,900<<20,stdin);
n=read();q=read();
size=150;
for(int i=1;i<=n;i++)
{
a[i]=read();
}
l[1]=1;
r[1]=size;
num=n/size+(n%size!=0);
for(int i=2;i<=num;i++)
{
l[i]=r[i-1]+1;
r[i]=min(n,l[i]+size-1);
}
for(int i=1;i<=num;i++)
{
for(int j=l[i];j<=r[i];j++)
{
blk[j]=a[j];
belong[j]=i;
}
blk_sort(i);
}
while(q--)
{
int opt,l1,r1,k;
opt=read();l1=read();r1=read();k=read();
if(opt==2)
{
int a1=belong[l1],b=belong[r1];
if(a1==b)
{
for(int i=l1;i<=r1;i++)a[i]+=k;
reset(a1);
continue;
}
for(int i=l1;i<=r[a1];i++)a[i]+=k;
reset(a1);
for(int i=l[b];i<=r1;i++)a[i]+=k;
reset(b);
for(int i=a1+1;i<b;i++)bl[i]+=k;
}
else
{
print(kth(l1,r1,k)),EL;
}
}
fwrite(out,1,wz,stdout);
return 0;
}