分块

int belong[maxn];//belong[i] 代表第i个数属于第几块 
int sum[maxn];//sum[i] 代表第i块的和是多少 
int daxiao[maxn];//daxiao[i] 代表第i块的大小是多少 
int col[maxn];//col[i] 代表第i块被整体加了col[i] 
int main()
{
	cin >> n >> m;
	for (int i=1;i<=n;i++)
		cin >> a[i];
	int s = sqrt(n);//每块的大小 
	for (int i=1;i<=n;i++)
		belong[i] = i/s+1;
	for (int i=1;i<=n;i++)
	{
		sum[belong[i]] += a[i];
		daxiao[belong[i]] ++;
	}
		
	for (int x=1;x<=m;x++)
	{
		int opt;
		cin >> opt;
		if (opt == 1)//询问操作
		{
			int l,r;
			cin >> l >> r;
			int ans=0;
			if (belong[l] == belong[r])
				for (int i=l;i<=r;i++)
					ans += a[i] + col[belong[i]];
			else
			{
				for (int i=l;belong[i] == belong[l]; i++)
					ans += a[i] + col[belong[i]];
				for (int i=r;belong[i] == belong[r]; i--)
					ans += a[i] + col[belong[i]];
				for (int i=belong[l] + 1; i < belong[r]; i++)
					ans += sum[i];
			}
			cout << ans << "\n";
		} 
		else
		{
			int l,r,v;
			cin >> l >> r >> v;
			if (belong[l] == belong[r])
				for (int i=l;i<=r;i++)
					a[i] += v;
			else
			{
				for (int i=l;belong[i] == belong[l]; i++)
					a[i] += v,sum[belong[i]] += v;
				for (int i=r;belong[i] == belong[r]; i--)
					a[i] += v,sum[belong[i]] += v;
				for (int i=belong[l] + 1; i < belong[r]; i++)
				{
					sum[i] += v * daxiao[i];
					col[i] += v; 
				}
			}
		}
	}
	
	return 0;
}
posted @ 2025-06-21 20:34  Fire_poetry  阅读(8)  评论(0)    收藏  举报