加载中…

返回上一页

分块——敌兵布阵

敌兵布阵
#include<bits/stdc++.h>
using namespace std;
int n,a[1001],sum[1001],Add[1001];
//sum[i]是第i段的区间和,Add是整段的修改标记(本题用不到)
int L[1001],R[1001],tot;//每段的左右端点
int len,pos[1001];//每一个位置属于哪一段
string s;
void init(int l,int r)
{
	len=sqrt(r-l+1);
	tot=0;
	for(int i=l;i<=r;i++)
	{
		pos[i]=1+(i-l)/len;
		tot=max(tot,pos[i]);
		sum[pos[i]]+=a[i];
		if(i==l) L[pos[i]]=i;
		if(i==r) R[pos[i]]=i;
		if(l<i && i<r && pos[i-1]!=pos[i])
		{
			L[pos[i]]=i;
			R[pos[i-1]]=i-1;
		}
	}
}
void add(int x,int y)
{
	a[x]+=y;
	sum[pos[x]]+=y;
}
int ask(int l,int r)
{
	int p=pos[l],q=pos[r];
	int ans=0;
	if(p==q) for(int i=l;i<=r;i++) ans+=a[i];
	else
	{
		for(int i=l;i<=R[p];i++) ans+=a[i];
		for(int i=p+1;i<q;i++) ans+=sum[i];
		for(int i=L[q];i<=r;i++) ans+=a[i];
	}
	return ans;
}
int main()
{
	int t,nn=0;
	cin>>t;
	for(int _=1;_<=t;_++)
	{
		memset(sum,0,sizeof(sum));
		cin>>n;
		for(int i=1;i<=n;i++) cin>>a[i];
		init(1,n);
		cout<<"Case "<<++nn<<':'<<endl;
		while(cin>>s)
		{
			if(s[0]=='E') break;
			if(s[0]=='Q')
			{
				int l,r;
				cin>>l>>r;
				cout<<ask(l,r)<<endl;
			}
			if(s[0]=='A')
			{
				int x,y;
				cin>>x>>y;
				add(x,y);
			}
			if(s[0]=='S')
			{
				int x,y;
				cin>>x>>y;
				add(x,-y);
			}
		}
	}
	return 0;
}
posted @ 2022-02-09 19:30  1Liu  阅读(17)  评论(0)    收藏  举报