树状数组模版(单点修改区间求和)(区间修改单点求值)(区间修改区间求和)

eg。

hdu1166(单点修改区间求和)

#include
#define maxn 111111
using namespace std;
int n;
int c[maxn];
int b[maxn];
int lowbit(int x) {
    return x&-x;
}
/**单点修改区间求和**/
/**
add(x,num);
sum(r)-sum(l-1);
每次x号位置修改num
求lr闭区间的和
**/

void add(int k,int num) {
    while(k<=n) {
        c[k]+=num;
        k+=lowbit(k);
    }
}
int sum(int k) {
    int ans=0;
    while(k) {
        ans+=c[k];
        k-=lowbit(k);
    }
    return ans;
}
int main()
{
    int t;
    int kase=0;
    scanf("%d",&t);
    while(t--) {
        memset(c,0,sizeof c);
        printf("Case %d:\n",++kase);
        scanf("%d",&n);
        int x,y;
        for(int i=1;i<=n;i++) {
            scanf("%d",&x);
            add(i,x);
        }
        char s[10];
        while(scanf("%s",s)&&strcmp(s,"End")!=0) {
            if(strcmp(s,"Query")==0) {
                scanf("%d%d",&x,&y);
                printf("%d\n",sum(y)-sum(x-1));
            }
            else {
                if(strcmp(s,"Add")==0) {
                    scanf("%d%d",&x,&y);
                    add(x,y);
                }
                else {
                    scanf("%d%d",&x,&y);
                    add(x,-y);
                }
            }
        }
    }
    return 0;
}


hdu 1556(区间修改单点求值)

#include
#define maxn 111111
using namespace std;
int n;
int c[maxn];
int b[maxn];
int lowbit(int x) {
    return x&-x;
}
/**区间修改单点询问**/
/**
add(l-1,-num);add(r,num);
sum(x);
每次修改闭区间lr的值,询问x节点的值
**/

void add(int k,int num) {
    while(k) {
        b[k]+=num;
        k-=lowbit(k);
    }
}
int sum(int k) {
    int ans=0;
    while(k<=n) {
        ans+=b[k];
        k+=lowbit(k);
    }
    return ans;
}
int main()
{
     while(scanf("%d",&n)&&(n!=0)) {
        memset(b,0,sizeof b);
        int x,y;
        for(int i=1;i<=n;i++) {
            scanf("%d%d",&x,&y);
            add(x-1,-1);
            add(y,1);
        }
        for(int i=1;i

自己测试的(区间修改区间求和)

#include
#define maxn 111111
using namespace std;
int n;
int c[maxn];
int b[maxn];
int lowbit(int x) {
    return x&-x;
}
/**区间修改区间求和**/
/**
add_b(r,num);add_c(r,num);
if(l>1) {
    add_b(l-1,-num);add_c(l-1,-num);
}
sum(r)-sum(l-1);
**/
void add_b(int x,int num) {
    for(int i=x;i>0;i-=lowbit(i))
        b[i]+=num;
}
void add_c(int x,int num) {
    for(int i=x;i<=n;i+=lowbit(i))
        c[i]+=x*num;
}
int sum_b(int x) {
    int ans=0;
    for(int i=x;i<=n;i+=lowbit(i))
        ans+=b[i];
    return ans;
}
int sum_c(int x) {
    int ans=0;
    for(int i=x;i>0;i-=lowbit(i))
        ans+=c[i];
    return ans;
}
int sum(int x) {
    if(x) return sum_b(x)*x+sum_c(x-1);
    else return 0;
}
int main()
{
    char s[10];
    memset(b,0,sizeof b);
    memset(c,0,sizeof c);
    scanf("%d",&n);
    while(scanf("%s",s)!=EOF) {
        int x,y,num;
        if(strcmp(s,"A")==0) {
            scanf("%d%d%d",&x,&y,&num);
            add_b(y,num);add_c(y,num);
            if(x>1) {
                add_b(x-1,-num);add_c(x-1,-num);
            }
        }
        else {
            scanf("%d%d",&x,&y);
            printf("%d\n",sum(y)-sum(x-1));
        }
        for(int i=1;i<=10;i++) {
            cout << b[i] << " ";
        }
        cout << endl;
        for(int i=1;i<=10;i++) {
            cout << c[i] << " ";
        }
        cout << endl;
    }
    return 0;
}



你可能感兴趣的:(一些模板,树状数组)