MnZn刚学OI一毫秒分块大红大紫
查看原帖
MnZn刚学OI一毫秒分块大红大紫
370916
yemengzhi楼主2024/12/25 15:51

RT,全部RE了,不知道是什么问题

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define inf 2147483647
inline int read(){
	int f=1,x=0;
	char ch=getchar();
	while(ch<'0'||ch>'9'){
		if(ch=='-')
			f=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9')
		x=x*10+ch-'0',ch=getchar();
	return x*f;
 } 
inline void write(int x){
	if(x<0)	x=-x,putchar('-');
	if(x>9)	write(x/10);
	putchar(x%10+'0');
}
int n,m;
int a[100100];
int b[100100];
int add[10001];
//int sum[100100];
int st[10001],ed[10010];
int pos[10001];
void init(){
	int block=sqrt(n);
	int t=n/block;
	if(n%block)	t++;
	for(int i=1;i<=t;i++){
		st[i]=(i-1)*block+1;
		ed[i]=i*block;
	}
	ed[t]=n;
	for(int i=1;i<=t;i++)	sort(b+st[i],b+ed[i]+1);
	for(int i=1;i<=n;i++)	pos[i]=(i-1)/block+1;
	//for(int i=1;i<=t;i++)
	//	for(int j=st[i];j<=ed[i];j++)	
	//		sum[i]+=a[j];
}
int check(int l,int r,int k){
	int p=pos[l],q=pos[r];
	int cnt=0;
	if(p==q){
		for(int i=l;i<=r;i++)	if(a[i]+add[p]<=k)	cnt++;
		return cnt;
	}
	for(int i=l;i<=ed[p];i++)	if(a[i]+add[p]<=k)	cnt++;
	for(int i=p+1;i<=q-1;i++){
		int ll=st[i],rr=ed[i],mid;
		if(b[ll]+add[i]>k)	continue;
		if(b[rr]+add[i]<=k){
			cnt+=rr-ll+1;
			continue;
		}
		while(ll<rr){
			mid=(ll+rr>>1)+1;
			if(b[mid]+add[i]<=k)	ll=mid;
			else	rr=mid-1;
		}
		if(b[ll]+add[i]<=k)	cnt+=ll-st[i]+1;
	}
	for(int i=st[q];i<=r;i++)	if(a[i]+add[q]<=k)	cnt++;
	return cnt;
}
int getmin(int x,int y){
	int p=pos[x],q=pos[y];
	int ans=inf;
	if(p==q){
		for(int i=x;i<=y;i++)	ans=min(ans,a[i]+add[p]);
		return ans;
	}
	for(int i=x;i<=ed[p];i++)	ans=min(ans,a[i]+add[p]);
	for(int i=p+1;i<=q-1;i++)	ans=min(ans,b[st[i]]+add[i]);
	for(int i=st[q];i<=y;i++)	ans=min(ans,a[i]+add[q]);
	return ans;
}
int getmax(int x,int y){
	int p=pos[x],q=pos[y];
	int ans=-inf;
	if(p==q){
		for(int i=x;i<=y;i++)	ans=max(ans,a[i]+add[p]);
		return ans;
	}
	for(int i=x;i<=ed[p];i++)	ans=max(ans,a[i]+add[p]);
	for(int i=p+1;i<=q-1;i++)	ans=max(ans,b[ed[i]]+add[i]);
	for(int i=st[q];i<=y;i++)	ans=max(ans,a[i]+add[q]);
	return ans;
}
void query(int l,int r,int k){
	int p=pos[l],q=pos[r];
	if(p==q){
		for(int i=l;i<=r;i++)	a[i]+=k;
//		sum[p]+=k*(r-l+1);
		for(int i=st[p];i<=ed[p];i++)	b[i]=a[i];
		sort(b+st[p],b+ed[p]+1);
		return;
	}
	else{
		for(int i=l;i<=ed[p];i++)	a[i]+=k;
//		sum[p]+=k*(ed[p]-l+1);
		for(int i=st[p];i<=ed[p];i++)	b[i]=a[i];
		sort(b+st[p],b+ed[p]+1);
		for(int i=p+1;i<=q-1;i++)	add[i]+=k;
		for(int i=st[q];i<=r;i++)	a[i]+=k;
//		sum[q]+=k*(r-st[q]+1);
		for(int i=st[q];i<=ed[q];i++)	b[i]=a[i];
		sort(b+st[q],b+ed[q]+1);
	}
} 
void searchs(int l,int r,int k){
	int ans=-1;
	int lf,ri,mid;
	lf=getmin(l,r);
	ri=getmax(l,r);
	while(lf<=ri){
		mid=lf+ri>>1;
		if(check(lf,ri,mid)<k)	lf=mid+1;
		else	ri=mid-1,ans=mid;
	}
	cout<<ans;
	puts("");
}
signed main(){
	IOS
	cin>>n>>m;
	for(int i=1;i<=n;i++)	cin>>a[i],b[i]=a[i];
	init();	
	while(m--){
		int l,r,k,opt;
		cin>>opt>>l>>r>>k;
		if(opt==1){
			if(k<1||k>r-l+1){
				write(-1),puts("");
				continue;
			}
			searchs(l,r,k);
		}
		else{
			query(l,r,k);
		}
	}
}

马蜂不好,函数名乱取的呵呵

2024/12/25 15:51
加载中...