数列分块入门 2 总结

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Larry1118/article/details/86652363

在这里插入图片描述
这题,呜呜呜。。。。
我™改了™的好几天啊啊啊啊啊!!!!!
这题依旧分块。原序列设为a[]
对于每个块,我们可以用一个数组排序(在此设为d[])。

另一个!!!

我不知道为什么,将原序列记录了位置在排序™还是错了。。。
然后,还是分类讨论。

opt==0

分成三块。
1:l所在的凸出来的那一部分,暴力搞,然后将a[]中l的块暴力赋给d[],并排序。
2:r所在的凸出来的那一部分,方法同上。
3:中间的整个的一些块,由于不影响其单调性,所以我们可以设个b[]来加。

当然,如果l和r在同一个块中的话要特判!

opt==1

分成三块。
1:l所在的凸出来的那一部分,暴力搞。
2:r所在的凸出来的那一部分,方法同上。
3:中间的整个的一些块,由于单调,可以二分来求每一块中符合的个数。

当然,如果l和r在同一个块中的话要特判!

嗯嗯,大概就这些了。
上标:

#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
int a[50010],d[50010],n,b[231];
int opt,l,r,c,st;
int bl[50010],le[231],ri[231];

inline int read()
{
	int x=0,f=0; char c=getchar();
	while (c<'0' || c>'9') f=(c=='-') ? 1:f,c=getchar();
	while (c>='0' && c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
	return f ? -x:x;
}

void update(int x)
{
	for (int i=le[x];i<=ri[x];i++) d[i]=a[i];
	sort(d+le[x],d+ri[x]+1);
}

void add(int l,int r,int c)
{
	for (int i=l;i<=min(ri[bl[l]],r);i++) a[i]+=c;
	update(bl[l]);
	if (bl[l]!=bl[r])
	{
		for (int i=le[bl[r]];i<=r;i++) a[i]+=c;
		update(bl[r]);
	}
	for (int i=bl[l]+1;i<=bl[r]-1;i++) b[i]+=c;
}

int query(int l,int r,int c)
{
	int ans=0;
	for (int i=l;i<=min(ri[bl[l]],r);i++)
		if (a[i]+b[bl[l]]<c) ans++;
	if (bl[l]!=bl[r])
	{
		for (int i=le[bl[r]];i<=r;i++)
			if (a[i]+b[bl[r]]<c) ans++;
	}
	for (int i=bl[l]+1;i<=bl[r]-1;i++)
	{
		int L=le[i],R=ri[i],mid,s=0;
		while (L<=R)
		{
			mid=L+R>>1;
			if (d[mid]+b[i]<c) s=mid,L=mid+1;
			else R=mid-1;
		}
		if (s) ans+=s-le[i]+1;
	}
	return ans;
}

int main()
{
	freopen("6278.in","r",stdin);
	freopen("6278.out","w",stdout);
	n=read();st=sqrt(n);
	for (int i=1;i<=n;i++) a[i]=d[i]=read();
	for (int i=1;i<=n;i++)
	{
		bl[i]=(i-1)/st+1;
		if (!le[bl[i]]) le[bl[i]]=i;
		ri[bl[i]]=i;
	}
	for (int i=1;i<=bl[n];i++)
		sort(d+le[i],d+ri[i]+1);
	for (int i=1;i<=n;i++)
	{
		opt=read(),l=read(),r=read(),c=read();
		if (opt==0) add(l,r,c);
		else printf("%d\n",query(l,r,c*c));
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/Larry1118/article/details/86652363