萌新求调,后五个点WA,分块写炸了
查看原帖
萌新求调,后五个点WA,分块写炸了
316681
zhongshizhao1楼主2022/8/13 15:56
#include <iostream>
#include <cstring>
#include <cmath>
using namespace std;
long long a[100005],block[100005],add[100005],maxn[100005],he[100005];
long long sn;
void fk(long long l,long long r)
{
	for(long long i=l;i<=min(r,block[l]*sn);i++)
	{
		if(a[i]<=1)continue;
		else
		{
			long long t=a[i];
			a[i]=sqrt(a[i]);
			he[block[i]]-=(t-a[i]);
			if(a[i]<=1)maxn[block[i]]--;
		}
	}
	if(block[l]==block[r])return;
	for(long long i=(block[r]-1)*sn+1;i<=r;i++)
	{
		if(a[i]<=1)continue;
		else
		{
			long long t=a[i];
			a[i]=sqrt(a[i]);
			he[block[i]]-=(t-a[i]);
			if(a[i]<=1)maxn[block[i]]--;
		}
	}
	for(long long i=block[l]+1;i<=block[r]-1;i++)
	{
		if(maxn[i]!=0)
		{
			for(long long j=(i-1)*sn+1;j<=i*sn;j++)
			{
				if(a[j]<=1)continue;
				else
				{
					long long t=a[j];
					a[j]=sqrt(a[j]);
					he[i]-=(t-a[j]);
					if(a[j]<=1)maxn[i]--;
				}
				if(maxn[i]==0)break;
			}
		}
	}
}
long long check(long long l,long long r)
{
	long long sum=0;
	for(long long i=l;i<=min(r,block[l]*sn);i++)
	{
		sum+=a[i];
	}
	if(block[l]==block[r])return sum;
	for(long long i=(block[r]-1)*sn+1;i<=r;i++)
	{
		sum+=a[i];
	}
	for(long long i=block[l]+1;i<=block[r]-1;i++)
	{
		sum+=he[i];
	}
	return sum;
}
int main()
{
	//freopen("P4145_6","r",stdin);
	long long n,m;
	cin>>n;
	sn=sqrt(n);
	long long kuaibefore=1;
	long long maxx=0;
	for(long long i=1;i<=n;i++)
	{
		cin>>a[i];
		block[i]=(i-1)/sn+1;
		he[block[i]]+=a[i];
		if(a[i]>1)maxn[block[i]]++;
	}
	cin>>m;
	long long a,x,y;
	for(long long i=1;i<=m;i++)
	{
		cin>>a>>x>>y;
		if(a==0)
		{
			fk(x,y);
		}
		else
		{
			cout<<check(x,y)<<endl;
		}
	}
	return 0;
}
2022/8/13 15:56
加载中...