分块——敌兵布阵
敌兵布阵
#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;
}
--END--

浙公网安备 33010602011771号
我的博客: 𝟷𝙻𝚒𝚞
本文链接: https://www.cnblogs.com/1Liu/p/15876394.html
版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!