社区讨论

0pts求条,悬5关注

P13978数列分块入门 3参与者 2已保存回复 1

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
1 条
当前快照
1 份
快照标识符
@mjmn6a7i
此快照首次捕获于
2025/12/26 17:00
2 个月前
此快照最后确认于
2025/12/28 09:20
2 个月前
查看原帖
ac on #9 #21
CPP
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define falg flag
const int N=2e5;
int n;
int bsz,tot;
int a[N+5],b[N+5];
int tag[N+5];
void out()
{
	for(int i=1;i<=n;i++)
		cout<<a[i]<<" ";
	cout<<"\n";
	for(int i=1;i<=n;i++)
		cout<<b[i]<<" ";
	cout<<"\n";
	for(int i=1;i<=n;i++)
		cout<<tag[i]<<" ";
	cout<<"\n";
}
signed main()
{
	cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i],b[i]=a[i];
	bsz=sqrt(n);
	tot=(n-1)/bsz+1; //总块数
	for(int i=1;i<=tot;i++)
		sort(b+(i-1)*bsz+1,b+min(i*bsz,n)+1);
	for(int i=1;i<=n;i++)
	{
		int opt,l,r,c;
		cin>>opt>>l>>r>>c;
		int lb=(l-1)/bsz+1;
		int rb=(r-1)/bsz+1;
		int start,end;
		if(opt==0)
		{
			if(lb==rb)
			{
				start=(lb-1)*bsz+1,end=min(lb*bsz,n);
				for(int i=l;i<=r;i++) a[i]+=c;;
				for(int i=start;i<=end;i++) b[i]=a[i];
				sort(b+start,b+end+1);
			}
			else
			{
				start=(lb-1)*bsz+1,end=min(lb*bsz,n);
				//左边散点 
				for(int i=l;i<=end;i++) a[i]+=c;
				for(int i=start;i<=end;i++) b[i]=a[i];
				sort(b+start,b+end+1);
				//右边散点 
				start=(rb-1)*bsz+1,end=min(rb*bsz,n);
				for(int i=start;i<=r;i++) a[i]+=c;
				for(int i=start;i<=end;i++) b[i]=a[i];
				sort(b+start,b+end+1); 
				//整块 
				for(int i=lb+1;i<=rb-1;i++) tag[i]+=c;
			}
			
		}
		else
		{
			int x=c;
			int ans=-1;
//			out();
			if(lb==rb)
			{
				for(int i=l;i<=r;i++)
					if(a[i]+tag[lb]<x) ans=max(ans,a[i]+tag[lb]);
			}
			else
			{
				end=min(lb*bsz,n);
				for(int i=l;i<=end;i++)
					if(a[i]+tag[lb]<x) ans=max(ans,a[i]+tag[lb]);;
				start=(rb-1)*bsz+1;
				for(int i=start;i<=r;i++)
					if(a[i]+tag[rb]<x) ans=max(ans,a[i]+tag[rb]);;
				bool flag=true;
				for(int i=lb+1;i<=rb-1;i++)
				{
					start=(i-1)*bsz+1,end=min(i*bsz,n);
					int ll=start-1,rr=end+1;
					while(ll+1!=rr)
					{
						int mid=(ll+rr)>>1;
						if(b[mid]+tag[i]<x) ll=mid;
						else rr =mid;
					}
					if(ll>=start && b[ll]+tag[i]<x)
						ans=max(ans,b[ll]+tag[i]);
				}
			}
//			if(ans==0) cout<<-1<<"\n";
			cout<<ans<<"\n";
		}
	}
	return 0;
}

回复

1 条回复,欢迎继续交流。

正在加载回复...