敌兵布阵 HDU - 1166 (树状数组模板题,线段树模板题)

思路:就是树状数组的模板题,利用的就是单点更新和区间求和是树状数组的强项时间复杂度为m*log(n)

没想到自己以前把这道题当线段树的单点更新刷了。

树状数组:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn = 5e4 + ;
int tree[maxn], n;
void add(int k, int num)
{
while (k <= n)
{
tree[k] += num;
k += k&-k;
}
}
int sum(int k)
{
int sum = ;
while (k)
{
sum += tree[k];
k -= k&-k;
}
return sum;
}
int main()
{
int t, x, y, k=;
scanf("%d", &t);
while (t--)
{
memset(tree, , sizeof(tree));
scanf("%d", &n);
for (int i = ; i <= n; ++i)
{
scanf("%d", &x); add(i, x);
}
char num[];
printf("Case %d:\n", ++k);
while (scanf("%s", num), strcmp(num, "End") != )
{
scanf("%d%d", &x, &y);
if (strcmp(num,"Add")==){ add(x, y); }
else if (strcmp(num,"Sub")==){ add(x, -y); }
else{ printf("%d\n", sum(y) - sum(x-)); }
}
}
}

线段树

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define MID(a,b) (a+((b-a)>>1))
#define MAXN int(1e4)*5+5
struct node
{
int l, r;
int sum;
int mid(){ return MID(l, r); }
}; int num[MAXN], n; struct Tree
{
node tree[MAXN << ];
void build(int L, int R, int pos)
{
tree[pos].l = L; tree[pos].r = R; //表示区间
tree[pos].sum = ;
if (L == R){tree[pos].sum = num[R]; return; }//到了子叶
int mid = tree[pos].mid();
//二分
build(L, mid, pos<<);
build(mid + , R, pos << | );
tree[pos].sum = tree[pos << ].sum + tree[pos << | ].sum;
}
//valu 表示加的值, ind 表示第几个军营。(在区域中的位置)
void updata(int ind, int pos, int valu)
{
if (tree[pos].l == tree[pos].r)
{
tree[pos].sum += valu; return; //叶节点+valu
}
int mid = tree[pos].mid();
//二分查找单点位置?
if (ind <= mid) updata(ind, pos << , valu);
else updata(ind, pos << | , valu);
tree[pos].sum = tree[pos << ].sum + tree[pos << | ].sum;
//递归,覆盖上一层的sum
}
//查询
int query(int L, int R, int pos)//从根节点查到符合的区间节点
{
if (L <= tree[pos].l&&tree[pos].r <= R) return tree[pos].sum;
int mid = tree[pos].mid();
int sum1 = , sum2 = ;
if (L <= mid) sum1 = query(L, R, pos << );
if (R > mid) sum2 = query(L, R, pos << | );
return sum1 + sum2;
}
};
Tree tree;
int main()
{
int x, y;
int t, n,t_case=;
scanf("%d", &t);
while (t--)
{
char ch[];
scanf("%d", &n);
printf("Case %d:\n", ++t_case);
for (int i = ; i <= n; i++)
scanf("%d", &num[i]);
tree.build(, n, );
while (scanf("%s", ch) != EOF)
{
if (strcmp(ch, "End") == ) break;
else if (strcmp(ch,"Add")==)
{
scanf("%d%d", &x, &y);
tree.updata(x, , y);
}
else if (strcmp(ch, "Sub") == )
{
scanf("%d%d", &x, &y);
tree.updata(x, , -y);
}
else if (strcmp(ch, "Query") == )
{
scanf("%d%d", &x, &y);
printf("%d\n", tree.query(x, y, ));
}
}
}
return ;
}
上一篇:sqlmap查找SQL注入漏洞入门


下一篇:JVM总结-java对象的内存布局