分块50pts求调
查看原帖
分块50pts求调
820056
wmrqwqal & su楼主2023/10/28 22:23
#include<bits/stdc++.h>
using namespace std;
int n,m,a[1000010],sa[1000010],b[1000010],sq,tag[1000010],l[1000010],r[1000010],x,y,z;
char opt;
void upt(int id)
{
	for(register int i=l[id];i<=r[id];i++)
		sa[i]=a[i];
	sort(sa+l[id],sa+1+r[id]);
}
void add(int x,int y,int z)
{
	if(b[x]==b[y])
	{
		for(int i=x;i<=y;i++)
			a[i]+=z;
		upt(b[x]);
		return ;
	}
	for(register int i=x;i<=r[b[x]];i++)
		a[i]+=z;
	upt(b[x]);
	for(register int i=l[y];i<=y;i++)
		a[i]+=z;
	upt(b[y]);
	for(register int i=b[x]+1;i<=b[y]-1;i++)
		tag[i]+=z;
}
void query(int x,int y,int z)
{
	int ans=0;
	if(b[x]==b[y])
	{
		for(int i=x;i<=y;i++)
			if(a[i]+tag[b[i]]>=z)
				ans++;
		printf("%d\n",ans);
		return ;
	}
	for(register int i=x;i<=r[b[x]];i++)	
		if(a[i]+tag[b[i]]>=z)
			ans++;
	for(register int i=l[b[y]];i<=y;i++)
		if(a[i]+tag[b[i]]>=z)
			ans++;
	for(register int i=b[x]+1;i<=b[y]-1;i++)
	{
		int ll=l[i],rr=r[i],an=0,mid;
		while(ll<=rr)
		{
			mid=(ll+rr)>>1;
			if(sa[mid]+tag[i]>=z)
				rr=mid-1,an=r[i]-mid+1;
			else
				ll=mid+1;
		}
		ans+=an;
	}
	printf("%d\n",ans);
}
#define QwQ return 0;
int main()
{
	cin>>n>>m;
	sq=sqrt(n);
	for(register int i=1;i<=n;i++)
		scanf("%d",&a[i]);
	for(register int i=1;i<=n;i++)
	{
		l[i]-r[i-1]+1;
		r[i]=min(sq*i,n);
		for(register int j=l[i];j<=r[i];j++)
			b[j]=i,sa[j]=a[j];
		sort(sa+l[i],sa+1+r[i]);
		if(r[i]==n)
			break;
	}
	while(m--)
	{
		cin>>opt>>x>>y>>z;
		if(opt=='M')
			add(x,y,z);
		else
			query(x,y,z);
	}
	QwQ;
}
2023/10/28 22:23
加载中...