Input
第一行一个整数T,表示有T组数据。
每组数据第一行一个正整数N(N<=50000),表示敌人有N个工兵营地,接下来有N个正整数,第i个正整数ai代表第i个工兵营地里开始时有ai个人(1<=ai<=50)。
接下来每行有一条命令,命令有4种形式:
(1) Add i j,i和j为正整数,表示第i个营地增加j个人(j不超过30)
(2)Sub i j ,i和j为正整数,表示第i个营地减少j个人(j不超过30);
(3)Query i j ,i和j为正整数,i<=j,表示询问第i到第j个营地的总人数;
(4)End 表示结束,这条命令在每组数据最后出现;
每组数据最多有40000条命令
每组数据第一行一个正整数N(N<=50000),表示敌人有N个工兵营地,接下来有N个正整数,第i个正整数ai代表第i个工兵营地里开始时有ai个人(1<=ai<=50)。
接下来每行有一条命令,命令有4种形式:
(1) Add i j,i和j为正整数,表示第i个营地增加j个人(j不超过30)
(2)Sub i j ,i和j为正整数,表示第i个营地减少j个人(j不超过30);
(3)Query i j ,i和j为正整数,i<=j,表示询问第i到第j个营地的总人数;
(4)End 表示结束,这条命令在每组数据最后出现;
每组数据最多有40000条命令
Output
对第i组数据,首先输出“Case
i:”和回车,
对于每个Query询问,输出一个整数并回车,表示询问的段中的总人数,这个数保持在int以内。
对于每个Query询问,输出一个整数并回车,表示询问的段中的总人数,这个数保持在int以内。
Sample Input
1
10
1 2 3 4 5 6 7 8 9 10
Query 1 3
Add 3 6
Query 2 7
Sub 10 2
Add 6 3
Query 3 10
End
#include<cstdio> #include<algorithm> #include<cstring> #define ls x<<1 #define rs x<<1|1 using namespace std; const int N=50001; int tr[N<<2]; int T,Case,n; void bt(int l,int r,int x) { if (l==r) { int dat; scanf ("%d",&dat); tr[x]=dat; return; } int mid=(l+r)>>1; bt(l,mid,ls); bt(mid+1,r,rs); tr[x]=tr[ls]+tr[rs]; return; } void add(int q,int a,int l,int r,int x) { if (l==r) { tr[x]+=a; return; } int mid=(l+r)>>1; if (q<=mid) add(q,a,l,mid,ls); else add(q,a,mid+1,r,rs); tr[x]=tr[ls]+tr[rs]; return; } void sub(int q,int a,int l,int r,int x) { if (l==r) { tr[x]-=a; return ; } int mid=(l+r)>>1; if (q<=mid) sub(q,a,l,mid,ls); else sub(q,a,mid+1,r,rs); tr[x]=tr[ls]+tr[rs]; return ; } int que(int ql,int qr,int l,int r,int x) { if (ql<=l && qr>=r) { return tr[x]; } int mid=(l+r)>>1,ans=0; if (ql<=mid) ans+=que(ql,qr,l,mid,ls); if (qr>mid) ans+=que(ql,qr,mid+1,r,rs); return ans; } int main() { scanf ("%d",&T); while (T--) { Case++; printf("Case %d:\n",Case); memset(tr,0,sizeof(tr)); scanf ("%d",&n); bt(1,n,1); char s[15]; while (1) { getchar(); scanf ("%s",s); if (s[0]=='Q') { int l,r; scanf ("%d%d",&l,&r); printf("%d\n",que(l,r,1,n,1)); } else if (s[0]=='A') { int x,y; scanf ("%d%d",&x,&y); add(x,y,1,n,1); } else if (s[0]=='S') { int x,y; scanf ("%d%d",&x,&y); sub(x,y,1,n,1); } else break; } } return 0; }
Sample Output
Case 1:
6
33
59
十分基础的线段树模板,存一下。