分块Wa0求调或给较小hack
查看原帖
分块Wa0求调或给较小hack
770611
xxxxxzy楼主2023/10/20 21:06
#include<bits/stdc++.h>
#define int long long
#define MAX 100005
using namespace std;
inline int read(){
	int x=0,f=1;
	char ch=getchar();
	if(ch=='-') ch=getchar(),f=-1;
	while(ch>'9'||ch<'0') ch=getchar();
	while(ch<='9'&&ch>='0') x=x*10+ch-'0',ch=getchar();
	return (f==1?x:-x);
}
int n,m,op,l,r,k,a[MAX],siz,len,pos[MAX],p1[MAX],p2[MAX],p[MAX],lazy[MAX],minx[MAX],maxn[MAX],lef[MAX],rig[MAX];
struct num{
	int v,p;
}tt[MAX];
bool cmp(num a,num b){
	return a.v<b.v;
}
void merge(int l,int r,int lx,int rx,int k,int t){
	int cnt1=0,cnt2=0,now=0,tot1=0,tot2=0;
	for(int i=l;i<=r;i++){
		if(p[i]>=lx&&p[i]<=rx) a[p[i]]+=k,p1[++cnt1]=p[i];
		else p2[++cnt2]=p[i];
		minx[t]=min(minx[t],a[p[i]]);
		maxn[t]=max(maxn[t],a[p[i]]);
	}
	while(cnt1&&cnt2){
		if(a[p1[cnt1]]>a[p2[cnt2]]) p[r--]=p1[cnt1--];
		else p[r--]=p2[cnt2--];
	}
	while(cnt1) p[r--]=p1[cnt1--];
	while(cnt2) p[r--]=p2[cnt2--];
}
void change(int l,int r,int k){
	int fl=pos[l],fr=pos[r];
	if(fl==fr){
		merge((fl-1)*siz+1,min(fl*siz,n),l,r,k,fl);
		return;
	}
	for(int i=fl+1;i<=fr-1;i++) lazy[i]+=k,maxn[i]+=k,minx[i]+=k;
	merge(lef[fl],rig[fl],l,rig[fl],k,fl);
	merge(lef[fr],rig[fr],lef[fr],r,k,fr);
}
int get(int l,int r,int k,int laz){
//	cout<<l<<" "<<r<<" "<<k<<" "<<laz<<endl;
	if(a[p[l]]+laz>k) return 0;
	int beg=l;
	while(l<r){
		int mid=((l+r)>>1)+1;
		if(a[p[mid]]+laz>k) r=mid-1;
		else l=mid;
//		cout<<l<<" "<<r<<endl;
	}
	return l-beg+1;
}
int check(int lx,int rx,int rval){
	int ans=0;
	for(int i=pos[lx]+1;i<=pos[rx]-1;i++){
		ans+=get(lef[i],rig[i],rval,lazy[i]);
	}
//	cout<<ans<<endl;
	int fl=pos[lx],fr=pos[rx];
	if(fl==fr){
		for(int i=lx;i<=rx;i++){
			if(a[i]+lazy[i]<=rval) ans++;
		}
		return ans;
	}
	for(int i=lx;i<=rig[fl];i++){
		if(a[i]+lazy[fl]<=rval) ans++;
	}
	for(int i=lef[fr];i<=min(fr*siz,n);i++){
		if(a[i]+lazy[fr]<=rval) ans++;
	}
//	cout<<lx<<" "<<rx<<" "<<rval<<endl;
//	cout<<lx<<" "<<min(fl*siz,n)<<" "<<(fr-1)*siz+1<<" "<<min(fr*siz,n)<<" "<<ans<<endl;
	return ans;
}
int getmin(int l,int r){
	int fl=pos[l],fr=pos[r],ans=INT_MAX;
	for(int i=l;i<=rig[fl];i++) ans=min(ans,a[i]);
	for(int i=lef[fr];i<=r;i++) ans=min(ans,a[i]);
	for(int i=pos[l]+1;i<pos[r];i++) ans=min(ans,minx[i]);
	return ans;
}
int getmax(int l,int r){
	int fl=pos[l],fr=pos[r],ans=INT_MIN;
	for(int i=l;i<=rig[fl];i++) ans=max(ans,a[i]);
	for(int i=lef[fr];i<=r;i++) ans=max(ans,a[i]);
	for(int i=pos[l]+1;i<pos[r];i++) ans=max(ans,maxn[i]);
	return ans;
}
int ask(int l,int r,int k){
	if(k<1||k>r-l+1) return -1;
	int fl=getmin(l,r),fr=getmax(l,r),ans=-1;
//	cout<<fl<<" "<<fr<<endl;
	while(fl<=fr){
		int mid=(fl+fr)>>1;
		int sum=check(l,r,mid);
		if(sum<k) fl=mid+1;
		else if(sum==k) return mid;
		else fr=mid-1;
		ans=mid;
//		cout<<sum<<" "<<mid<<endl;
	}
	return ans;
}
signed main(){
	n=read(),m=read();
	for(int i=1;i<=n;i++) a[i]=read(),tt[i].v=a[i],tt[i].p=i;
	siz=sqrt(n);
	len=n/siz;
	if(n%siz!=0) len++;
	for(int i=1;i<=len;i++){
		int lx=(i-1)*siz+1,rx=min(i*siz,n);
		for(int j=lx;j<=rx;j++) pos[j]=i;
		lef[i]=lx,rig[i]=rx;
		sort(tt+lx+1,tt+rx+1,cmp);
		for(int j=lx;j<=rx;j++) p[j]=tt[j].p;
		minx[i]=a[p[lx]],maxn[i]=a[p[rx]];
//		cout<<minx[i]<<" "<<maxn[i]<<endl;
	}
	for(int i=1;i<=m;i++){
		op=read(),l=read(),r=read(),k=read();
		if(op==2) change(l,r,k);
		else cout<<ask(l,r,k)<<endl;
	}
}
2023/10/20 21:06
加载中...