hdu1166及树状数组模板
2014-07-08 07:43
375 查看
树状数组关键的两个函数如下,这两个函数掌握了,树状数组也就掌握了。具体原理各个大神都有了详细的解答,不加以累述,只提供一下模板
函数如下:
AC代码如下:
这题除了用树状数组来解之外,依旧可以用线段树解答,线段树相关代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#define rep(i,a,b) for (int i=a;i<=b;i++)
using namespace std;
struct P{
int sum,l,r;
}node[150050];
int n,num[50050]={0};
void build(int k,int l,int r){
node[k].l=l,node[k].r=r;
if (l==r) node[k].sum=num[l];
else {
build(2*k,l,(l+r)>>1);
build(2*k+1,((l+r)>>1)+1,r);
node[k].sum=node[2*k].sum+node[2*k+1].sum;
}
}
void update(int k,int i,int x){
if (node[k].l<=i&&node[k].r>=i) node[k].sum+=x;
if (node[k].l==node[k].r) return ;
if (i<=node[2*k].r) update(2*k,i,x);
else update(2*k+1,i,x);
}
int query(int k,int l,int r){
if (l==node[k].l&&r==node[k].r) return node[k].sum;
if (r<=node[2*k].r) return query(2*k,l,r);
if (l>=node[2*k+1].l) return query(2*k+1,l,r);
else return query(2*k,l,node[2*k].r)+query(2*k+1,node[2*k+1].l,r);
}
int main(){
int T;scanf("%d",&T);
rep(z,1,T){
memset(num,0,sizeof num);
scanf("%d",&n);
rep(i,1,n) scanf("%d",&num[i]);
build(1,1,n);
char s[100];
printf("Case %d:\n",z);
while (scanf("%s",s)){
if (s[0]=='E') break;
if (s[0]=='Q'){
int a,b;
scanf("%d%d",&a,&b);
printf("%d\n",query(1,a,b));
}
if (s[0]=='A'){
int a,x;
scanf("%d%d",&a,&x);
update(1,a,x);
}
if (s[0]=='S'){
int a,x;
scanf("%d%d",&a,&x);
update(1,a,-x);
}
}
}
return 0;
}
函数如下:
int sum(int i){ int s=0; while (i>0){ s+=num[i]; i-=i & -i; } return s; } void update(int i,int x){ while (i<=n){ num[i]+=x; i+=i & -i; } }
AC代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#define rep(i,a,b) for (int i=a;i<=b;i++)
using namespace std;
int n,num[50050]={0};
int sum(int i){ int s=0; while (i>0){ s+=num[i]; i-=i & -i; } return s; } void update(int i,int x){ while (i<=n){ num[i]+=x; i+=i & -i; } }
int main(){
int T;
scanf("%d",&T);
rep(z,1,T){
memset(num,0,sizeof num);
scanf("%d",&n);
rep(i,1,n){
int x;
scanf("%d",&x);
update(i,x);
}
char s[100];
printf("Case %d:\n",z);
while (1){
scanf("%s",s);
if (s[0]=='E') break;
if (s[0]=='Q'){
int a,b;
scanf("%d%d",&a,&b);
printf("%d\n",sum(b)-sum(a-1));
}
if (s[0]=='A'){
int a,x;
scanf("%d%d",&a,&x);
update(a,x);
}
if (s[0]=='S'){
int a,x;
scanf("%d%d",&a,&x);
update(a,-x);
}
}
}
return 0;
}
这题除了用树状数组来解之外,依旧可以用线段树解答,线段树相关代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#define rep(i,a,b) for (int i=a;i<=b;i++)
using namespace std;
struct P{
int sum,l,r;
}node[150050];
int n,num[50050]={0};
void build(int k,int l,int r){
node[k].l=l,node[k].r=r;
if (l==r) node[k].sum=num[l];
else {
build(2*k,l,(l+r)>>1);
build(2*k+1,((l+r)>>1)+1,r);
node[k].sum=node[2*k].sum+node[2*k+1].sum;
}
}
void update(int k,int i,int x){
if (node[k].l<=i&&node[k].r>=i) node[k].sum+=x;
if (node[k].l==node[k].r) return ;
if (i<=node[2*k].r) update(2*k,i,x);
else update(2*k+1,i,x);
}
int query(int k,int l,int r){
if (l==node[k].l&&r==node[k].r) return node[k].sum;
if (r<=node[2*k].r) return query(2*k,l,r);
if (l>=node[2*k+1].l) return query(2*k+1,l,r);
else return query(2*k,l,node[2*k].r)+query(2*k+1,node[2*k+1].l,r);
}
int main(){
int T;scanf("%d",&T);
rep(z,1,T){
memset(num,0,sizeof num);
scanf("%d",&n);
rep(i,1,n) scanf("%d",&num[i]);
build(1,1,n);
char s[100];
printf("Case %d:\n",z);
while (scanf("%s",s)){
if (s[0]=='E') break;
if (s[0]=='Q'){
int a,b;
scanf("%d%d",&a,&b);
printf("%d\n",query(1,a,b));
}
if (s[0]=='A'){
int a,x;
scanf("%d%d",&a,&x);
update(1,a,x);
}
if (s[0]=='S'){
int a,x;
scanf("%d%d",&a,&x);
update(1,a,-x);
}
}
}
return 0;
}
相关文章推荐
- hdu1166敌兵布阵(树状数组模板题)
- HDU1166 敌兵布阵 线段树||树状数组||CDQ分治 入门题复习
- P3374 【模板】树状数组 1 单点修改与区间查询
- 2018年全国多校算法寒假训练营练习比赛(第五场) (树状数组模板)
- 树状数组 HDU1166
- HDU1166 敌兵布阵 【树状数组】
- 二维树状数组模板
- hdu1166 敌兵布阵 一维树状数组
- (树状数组)hdu1166 敌兵布阵
- hdu1166敌兵布阵(大意)树状数组
- hdu 2642二维树状数组 单点更新区间查询 模板题
- hdu1166(树状数组入门)
- 树状数组模板
- 树状数组【模板】
- 【模板】逆序对(树状数组)
- 树状数组 模板:敌兵布阵
- hdu1166 敌兵布阵 +树状数组
- HDU1166 敌兵布阵【树状数组 OR 线段树】
- luogu P3374 【模板】树状数组 1
- HDU 1166 敌兵布阵 树状数组-(模板)