社区讨论
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 条回复,欢迎继续交流。
正在加载回复...