题意:给出每个位置的初始值,有三种操作,add,sub,query;add表示在第i个位置增加k,sub表示在第i个位置减少k,query表示求出第i到k个位置的所有数的和。
链接:http://acm.hdu.edu.cn/showproblem.php?pid=1166
思路:裸的树状数组,单点更新,区间查询。线段树也可以做,不过无论是时间复杂度,空间复杂度,编码复杂度,都是树状数组更方便。
注意点:无。
以下为AC代码:
Run ID | Submit Time | Judge Status | Pro.ID | Exe.Time | Exe.Memory | Code Len. | Language | Author |
12564396 | 2014-12-22 20:49:22 | Accepted | 1166 | 748MS | 1344K | 1346 B | C++ | luminous11 |
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
int n;
int num[50005];
void add( int x, int k )
{
for ( ; x <= n; x += ( x & -x ) )
num[x] += k;
}
int query ( int x )
{
int ans = 0;
for ( ; x > 0; x -= ( x & -x ) )
ans += num[x];
return ans;
}
int main()
{
ios::sync_with_stdio ( false );
int ncase;
cin >> ncase;
for ( int t = 1; t <= ncase; t ++ )
{
int l, r;
memset ( num, 0, sizeof ( num ) );
getchar();
cin >> n;
int tmp;
for ( int i = 1; i <= n; i ++ )
{
cin >> tmp;
add ( i, tmp );
}
cout << "Case " << t << ":" << endl;
char ch[100];
while ( cin >> ch )
{
if ( ch[0] == 'E' )break;
cin >> l >> r;
if ( ch[0] == 'Q' )
cout << query( r ) - query ( l - 1 ) << endl;
else if ( ch[0] == 'A' )
add ( l, r );
else if ( ch[0] == 'S' )
add ( l, -r );
getchar();
}
}
return 0;
}