社区讨论
救救孩子吧 必关
P13977数列分块入门 2参与者 4已保存回复 14
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 14 条
- 当前快照
- 1 份
- 快照标识符
- @mkmbrpdf
- 此快照首次捕获于
- 2026/01/20 16:21 4 周前
- 此快照最后确认于
- 2026/01/23 22:40 4 周前
分块+二分,WA on #1#8#11#19 ,其余 TLE 。
求调,悬关。
求调,悬关。
代码
CPP#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,len,a[200010],b[200010],bl[200010],lazy[1010];
inline int left(int k){return (k-1)*len+1;}
inline int right(int k){return min(k*len,n);}
inline void rebuild(int k)
{
int l=left(k),r=right(k);
if(l>r)return;
for(int i=l;i<=r;i++)a[i]=b[i];
sort(a+l,a+r+1);
}
inline void push_down(int k)
{
int l=left(k),r=right(k);
if(l>r)return;
for(int i=l;i<=r;i++)
{
a[i]+=lazy[k];
b[i]+=lazy[k];
}
lazy[k]=0;
}
signed main()
{
int m,op,l,r,c,x,L,R,mid,ans;
scanf("%lld",&n);
m=n,len=sqrt(n);
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
b[i]=a[i];
bl[i]=(i-1)/len+1;
}
for(int i=1;i<=n/len+1;i++)rebuild(i);
while(m--)
{
scanf("%lld%lld%lld%lld",&op,&l,&r,&c);
if(!op)
{
push_down(bl[l]);
push_down(bl[r]);
if(bl[l]==bl[r])
{
for(int i=l;i<=r;i++)b[i]+=c;
rebuild(bl[l]);
}
else
{
for(int i=l;i<=right(bl[l]);i++)
{
b[i]+=c;
rebuild(bl[l]);
}
for(int i=left(bl[r]);i<=r;i++)
{
b[i]+=c;
rebuild(bl[r]);
}
for(int i=bl[l]+1;i<bl[r];i++)lazy[i]+=c;
}
}
else
{
x=c*c;
push_down(bl[l]);
push_down(bl[r]);
ans=0;
for(int i=l;i<=right(bl[l]);i++)if(b[i]<x)ans++;
for(int i=left(bl[r]);i<=r;i++)if(b[i]<x)ans++;
for(int i=bl[l]+1;i<bl[r];i++)
{
L=left(i),R=right(i);
while(L<=R)
{
mid=(L+R)/2;
if(a[mid]<x-lazy[i])L=mid+1;
else R=mid-1;
}
ans+=(L-left(i));
}
printf("%lld\n",ans);
}
}
return 0;
}
回复
共 14 条回复,欢迎继续交流。
正在加载回复...