大佬求助
  • 板块学术版
  • 楼主KomorKomor
  • 当前回复1
  • 已保存回复1
  • 发布时间2024/7/3 14:38
  • 上次更新2024/7/3 15:48:52
查看原帖
大佬求助
1106289
KomorKomor楼主2024/7/3 14:38
#include <iostream>
#include <cmath>
#include <algorithm>
#define ll long long 
using namespace std;

int n,where[50010],d[50010],cpy[50010],cnt;//where数组储存的是数列中的每个元素所处第i个块
struct block
{
	int l;
	int r;
	ll sum=0,lazytag=0;
}a[200010];

void modify(int l,int r,int c)//修改区间
{
	int p=where[l],q=where[r];
	if(p==q)//如果左右端点在同一个块
	{
		for(int i=l;i<=r;i++)	d[i]+=c;
		for(int i=a[p].l;i<=a[p].r;i++)	cpy[i]=d[i];
		sort(cpy+a[p].l,cpy+a[p].r+1);
	}
	else
	{
		//先处理中间块
		for(int i=p+1;i<=q-1;i++)	a[i].lazytag+=c;
		for(int i=l;i<=a[p].r;i++)	d[i]+=c;
		for(int i=a[p].l;i<=a[p].r;i++)	cpy[i]=d[i];
		sort(cpy+a[p].l,cpy+a[p].r+1);
		for(int i=a[q].l;i<=r;i++)	d[i]+=c;
		for(int i=a[q].l;i<=a[q].r;i++)	cpy[i]=d[i];
		sort(cpy+a[q].l,cpy+a[p].r+1);
	}
}

int query(int l,int r,int c)
{
	int p=where[l],q=where[r],ans=0;
	if(p==q)
	{
		for(int i=l;i<=r;i++)	
			if(d[i]+a[p].lazytag<c)	ans++;
	}
	else
	{
		for(int i=p+1;i<=q-1;i++)	ans+=lower_bound(cpy+a[i].l,cpy+a[i].r+1,c-a[i].lazytag)-(cpy+a[i].l);
		for(int i=l;i<=a[p].r;i++)	if(d[i]+a[p].lazytag<c)	ans++;
		for(int i=a[q].l;i<=r;i++)	if(d[i]+a[q].lazytag<c)	ans++;
	}
	return ans;

}

int main()
{
	cin>>n;
	for(int i=1;i<=n;i++)	cin>>d[i],cpy[i]=d[i];//输入原数组
	int blk_size=sqrt(n);//每个块的大小
	for(int i=1;i<=n;i++)
	{
		where[i]=(i-1)/blk_size+1;
		a[where[i]].sum+=d[i];
		if((i-1)%blk_size==0)	a[++cnt].l=i;
		else if((i%blk_size==0))	a[cnt].r=i;
	}

	for(int i=1;i<=cnt;i++)	sort(cpy+a[i].l,cpy+a[i].r+1);

	for(int i=1;i<=n;i++)
	{
		int op,l,r,c;
		cin>>op>>l>>r>>c;
		if(op==0)	modify(l,r,c);
		else cout<<query(l,r,c*c)<<endl;
	}

	return 0;
}

大佬们看看,这段代码是分块求给定区间中有几个数小于某个值的,调破防了

2024/7/3 14:38
加载中...