这道题数据量很大,用朴素的方法做每个操作的时间复杂度为o(n)会超时,如果用线段树则每个操作为o(logn).
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <climits>
#include <set>
using namespace std;
#define maxn 50005
struct node{
int l, r, s;
}T[maxn*3];
int p[maxn];
int Build(int n, int l, int r)
{
T[n].l = l;
T[n].r = r;
if(l == r){
return T[n].s = p[l];
}
int mid = (l + r) / 2;
return T[n].s = Build(n<<1, l, mid) + Build(n<<1|1, mid+1, r);
}
void Update(int n, int m, int k)
{
if(T[n].l == T[n].r){
T[n].s = k;
return ;
}
int mid = (T[n].l + T[n].r) / 2;
if(m <= mid)
Update(n<<1, m, k);
else
Update(n<<1|1, m, k);
T[n].s = T[n<<1].s + T[n<<1|1].s;
}
void Query(int n, int l, int r, int &sum)
{
if(T[n].l == l && T[n].r == r){
sum += T[n].s;
return ;
}
int mid = (T[n].l + T[n].r) / 2;
if(r <= mid)
Query(n<<1, l, r, sum);
else if(l > mid)
Query(n<<1|1, l, r, sum);
else {
Query(n<<1, l, mid, sum);
Query(n<<1|1, mid+1, r, sum);
}
}
int main()
{
// freopen("in.txt", "r", stdin);
int t, cas = 0;
cin >> t;
while(t--)
{
printf("Case %d:\n", ++cas);
string s;
int n, a, b;
cin >> n;
for(int i = 1; i <= n; i++)
scanf("%d", p+i);
Build(1, 1, n);
while(cin >> s && s[0] != 'E')
{
if(s[0] == 'Q')
{
int sum = 0;
cin >> a >> b;
Query(1, a, b, sum);
cout << sum << endl;
}
else if(s[0] == 'A')
{
cin >> a >> b;
p[a] += b;
Update(1, a, p[a]);
}
else if(s[0] == 'S')
{
cin >> a >> b;
p[a] -= b;
Update(1, a, p[a]);
}
}
}
return 0;
}