确定问题再check函数的中间整块处理上,求助:
int htk(int l1,int r1,int c)
{
int ans=0;
int a1=belong[l1],b=belong[r1];
if(a1==b)
{
for(register int i=l1;i<=r1;i++)ans+=(a[i]+bl[a1]<=c);
return ans;
}
for(register int i=l1;i<=r[a1];i++)ans+=(a[i]+bl[a1]<=c);
for(register int i=l[b];i<=r1;i++)ans+=(a[i]+bl[b]<=c);
for(register int i=a1+1;i<b;i++)
{
if(blk[l[i]]+bl[i]>c)continue;
if(blk[r[i]]+bl[i]<c){ans+=(r[i]-l[i]+1);continue;}
ans+=upper_bound(blk+l[i],blk+r[i]+1,c-bl[i])-blk-l[i];
}
return ans;
/*
int ans=0;
for(int i=l1;i<=r1;i++)
{
if(a[i]+bl[belong[i]]<=c)ans++;
}
return ans;
*/
}
全部代码:
/*
Author:zyh
date:
submit:
Ads:
{
https://www.luogu.com.cn/user/242524
https://www.luogu.com.cn/blog/242524/
https://codeforces.com/profile/Zhaoyuhang2008
}
I'm a juruo qwq
*/
#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[1000],r[1000],a[100008],size,q,belong[100008],num,blk[100008],bl[1000];
inline void blk_sort(int x){sort(blk+l[x],blk+r[x]+1);}
int htk(int l1,int r1,int c)
{
int ans=0;
int a1=belong[l1],b=belong[r1];
if(a1==b)
{
for(register int i=l1;i<=r1;i++)ans+=(a[i]+bl[a1]<=c);
return ans;
}
for(register int i=l1;i<=r[a1];i++)ans+=(a[i]+bl[a1]<=c);
for(register int i=l[b];i<=r1;i++)ans+=(a[i]+bl[b]<=c);
for(register int i=a1+1;i<b;i++)
{
if(blk[l[i]]+bl[i]>c)continue;
if(blk[r[i]]+bl[i]<c){ans+=(r[i]-l[i]+1);continue;}
ans+=upper_bound(blk+l[i],blk+r[i]+1,c-bl[i])-blk-l[i];
}
return ans;
/*
int ans=0;
for(int i=l1;i<=r1;i++)
{
if(a[i]+bl[belong[i]]<=c)ans++;
}
return ans;
*/
}
int getmax(int l1,int r1)
{
int ans=-0x3f3f3f3f;
int a1=belong[l1],b=belong[r1];
if(a1==b)
{
for(register int i=l1;i<=r1;i++)ans=max(ans,a[i]+bl[a1]);
return ans;
}
for(register int i=l1;i<=r[a1];i++)ans=max(ans,a[i]+bl[a1]);
for(register int i=l[b];i<=r1;i++)ans=max(ans,a[i]+bl[b]);
for(register int i=a1+1;i<b;i++)ans=max(ans,blk[r[i]]+bl[i]);
return ans;
}
int getmin(int l1,int r1)
{
int ans=0x3f3f3f3f;
int a1=belong[l1],b=belong[r1];
if(a1==b)
{
for(register int i=l1;i<=r1;i++)ans=min(ans,a[i]+bl[a1]);
return ans;
}
for(register int i=l1;i<=r[a1];i++)ans=min(ans,a[i]+bl[a1]);
for(register int i=l[b];i<=r1;i++)ans=min(ans,a[i]+bl[b]);
for(register int i=a1+1;i<b;i++)ans=min(ans,blk[l[i]]+bl[i]);
return ans;
}
int kth(int l1,int r1,int k)
{
int l=getmin(l1,r1),r=getmax(l1,r1),ans=-1;
for(int i=l;i<=r;i++)
{
if(htk(l1,r1,i)==k)
{
ans=i;
break;
}
}
return ans;
}
int main()
{
fread(re=ibuf,1,900<<20,stdin);
n=read();q=read();
size=3;
for(register int i=1;i<=n;i++)
{
a[i]=read();
}
l[1]=1;
r[1]=size;
num=n/size+(n%size!=0);
for(register int i=2;i<=num;i++)
{
l[i]=r[i-1]+1;
r[i]=min(n,l[i]+size-1);
}
for(register int i=1;i<=num;i++)
{
for(register 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(register int i=l1;i<=r1;i++)
{
a[i]+=k;
blk[i]+=k;
}
blk_sort(a1);
goto db;
}
for(register int i=l1;i<=r[a1];i++)
{
a[i]+=k;
blk[i]+=k;
}
blk_sort(a1);
for(register int i=l[b];i<=r1;i++)
{
a[i]+=k;
blk[i]+=k;
}
blk_sort(b);
for(register int i=a1+1;i<b;i++)bl[i]+=k;
db:
for(register int i=1;i<=n;i++)cout<<a[i]+bl[belong[i]]<<" ";
cout<<endl<<endl;;
;
}
else
{
print(kth(l1,r1,k)),EL;cout<<endl;
}
}
fwrite(out,1,wz,stdout);
return 0;
}
/*
10 10
-16893 2445 -13183 8601 -9115 504 -15669 4443 -15995 12453
2 8 9 11
2 4 10 -72
2 6 10 65
2 7 9 -79
2 1 6 -23
2 8 9 -55
1 8 10 3
1 7 10 4
1 1 8 5
1 1 5 4
*/
底下是挂了的样例。
不需考虑此代码任何会TLE的部分