#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<ctime>
#include<string>
#include<stack>
#include<deque>
#include<queue>
#include<list>
#include<set>
#include<map>
#include<cstdio>
#include<limits.h>
#define MOD 1000000007
#define fir first
#define sec second
#define fin freopen("/home/ostreambaba/文档/input.txt", "r", stdin)
#define fout freopen("/home/ostreambaba/文档/output.txt", "w", stdout)
#define mes(x, m) memset(x, m, sizeof(x))
#define Pii pair<int, int>
#define Pll pair<ll, ll>
#define INF 1e9+7
#define Pi 4.0*atan(1.0)
#define lowbit(x) (x&(-x))
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define scini(n) scanf("%d", &n)
#define scinii(n, m) scanf("%d%d", &n, &m)
#define scout(n) printf("%d\n", n);
typedef long long ll;
typedef unsigned long long ull;
const double eps = 1e-6;
const int maxn = 50010;
using namespace std;
int res[maxn];
void update(int i, int add) //更新,将第i个增加add大小
{
while(i <= N){
res[i] += add; //跟新与之相关的点
i += lowbit(i);
}
}
int sum(int n) //区间求和,求n项和
{
int ret = 0;
while(n > 0){
ret += res[n];
n -= lowbit(n);
}
}
int main()
{
// fin;
int N;
scini(N);
mes(res, 0);
int num;
for(int i = 1; i <= N; ++i){
scini(num);
update(i, num);
}
int n;
scini(n);
int ret = sum(n);
cout << ret << endl;
}
树状数组主要的三个部分(优雅美丽)
第一部分:
int lowbit(int n)
{
return n&(-n); //或者 return n&(n^(n-1));
}
作用: lowbit(n)是为了求出2^x(x为n的二进制表示的最右边的1的位置),例如3,二进制为11,最右边的1的位置为0,则lowbit(3)= 2^0 = 1;
例如6,二进制为110,,最右边的1的位置为1, 则lowbit(6)= 2^1 = 2;
第二部分:
void update(int i, int add) //更新,将第i个增加add大小
{
while(i <= N){
res[i] += add; //跟新与之相关的点
i += lowbit(i);
}
}
第三部分:
int sum(int n) //区间求和,求n项和
{
int ret = 0;
while(n > 0){
ret += res[n];
n -= lowbit(n);
}
}
题目:hdu1166 士兵杀敌
区间求和,单点更新
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<ctime>
#include<string>
#include<stack>
#include<deque>
#include<queue>
#include<list>
#include<set>
#include<map>
#include<cstdio>
#include<limits.h>
#define MOD 1000000007
#define fir first
#define sec second
#define fin freopen("/home/ostreambaba/文档/input.txt", "r", stdin)
#define fout freopen("/home/ostreambaba/文档/output.txt", "w", stdout)
#define mes(x, m) memset(x, m, sizeof(x))
#define Pii pair<int, int>
#define Pll pair<ll, ll>
#define INF 1e9+7
#define Pi 4.0*atan(1.0)
#define lowbit(x) (x&(-x))
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define scini(n) scanf("%d", &n)
#define scinii(n, m) scanf("%d%d", &n, &m)
#define scout(n) printf("%d\n", n);
typedef long long ll;
typedef unsigned long long ull;
const double eps = 1e-6;
const int maxn = 50010;
using namespace std;
int res[maxn];
int N;
void update(int i, int add)
{
while(i <= N){
res[i] += add;
i += lowbit(i);
}
}
int getSum(int n)
{
int ret = 0;
while(n > 0){
ret += res[n];
n -= lowbit(n);
}
return ret;
}
int main()
{
// fin;
int Case;
scini(Case);
for(int i = 1; i <= Case; ++i){
printf("Case %d:\n", i);
int num;
mes(res, 0);
scini(N);
for(int i = 1; i <= N; ++i){
scini(num);
update(i, num);
}
string op;
int l, r;
cin >> op;
while(op != "End"){
scinii(l, r);
if(op == "Query"){
int Sum = getSum(r) - getSum(l-1);
scout(Sum);
}
else if(op == "Add"){
update(l, r);
}
else{
update(l, -r);
}
cin >> op;
}
}
return 0;
}