树状数组 模板

树状数组的知识点:我的另一个博客

 

1.单点更新,求区间

 题目链接

#include<bits/stdc++.h>

using namespace std;
int n,m;
const int N=1e5+10;
int a[N];
int lowbit(int x)
{
    return x&(-x);
}

int sum(int x)
{
    int ans=0;
    for(int i=x;i>0;i-=lowbit(i)){
        ans+=a[i];
    }
    return ans;
}

void updata(int x,int y)
{
    for(int i=x;i<=n;i+=lowbit(i)){
        a[i]+=y;
    }
}
int main()
{
    while(scanf("%d %d",&n,&m)==2){
        memset(a,0,sizeof(a));
        for(int i=1;i<=n;i++){
            int x;
            scanf("%d",&x);
            updata(i,x);
        }
        while(m--){
            int k,x,y;
            scanf("%d %d %d",&k,&x,&y);
            if(k==1){
                updata(x,y);
            }
            else{
                printf("%d\n",sum(y)-sum(x-1));
            }
        }

    }
    return 0;
}

 

 

2.区间修改 求某点

 题目链接

//模板
#include<bits/stdc++.h>

using namespace std;
int lowbit(int x)
{
    return x&(-x);
}
int n;
const int N=1e5+10;
int s[N];
void updata(int x,int y)
{
    for(int i=x;i<=n;i+=lowbit(i)){
        s[i]+=y;
    }
}

int sum(int x)
{
    int ans=0;
    for(int i=x;i>0;i-=lowbit(i)){
        ans+=s[i];
    }
    return ans;
}
int main()
{
    while(scanf("%d",&n)==1,n){
        memset(s,0,sizeof(s));
        for(int i=0;i<n;i++){
            int a,b;
            scanf("%d %d",&a,&b);
            updata(a,1);
            updata(b+1,-1);
        }
        for(int i=1;i<=n;i++){
            if(i!=1) printf(" ");
            printf("%d",sum(i));
        }
        printf("\n");
    }
    return 0;
}

 

  模板

#include<cstdio>  
#include<cstring>  
#include<algorithm>  
#include<vector>  
using namespace std;  
#define ms(i,j) memset(i,j,sizeof i);  
int n,m;  
const int maxn = 500005;  
int a[maxn];//a记录的是比i-lowbit(i)多的值  
int lowbit(int x)  
{  
    return x&(-x);  
}  
int add(int x, int v)  
{  
    for (int i=x;i<=n;i+=lowbit(i))  
    {  
        a[i] += v;  
    }  
}  
int sub(int x)  
{  
    int ret = 0;  
    for (int i=x;i>0;i-=lowbit(i))  
    {  
        ret += a[i];  
    }  
    return ret;  
}  
int main()  
{  
    scanf("%d%d", &n ,&m);  
    ms(a,0);  
    for (int i=1;i<=n;i++)  
    {  
        int x;  
        scanf("%d", &x);  
        add(i,x);  
        add(i+1,-x);  
    }  
    for (int i=1;i<=m;i++)  
    {  
        int ty;  
        scanf("%d", &ty);  
        if(ty==1)  
        {  
            int x,y,k;  
            scanf("%d%d%d", &x,&y,&k);  
            add(x,k); add(y+1,-k);  
        } else   
        {  
            int x;  
            scanf("%d", &x);  
            printf("%d\n", sub(x));  
        }  
    }  
    system("pause");  
    return 0;  
}  

 

 

3,区间修改 区间查询

 题目链接

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>

using namespace std;
int n,m;
const int N=1e5+10;
long long s1[N],s2[N];
int lowbit(int x)
{
    return x&(-x);
}

void updata(int p,long long x)
{
    for(int i=p;i<=n;i+=lowbit(i)){
        s1[i]+=x;
        s2[i]+=x*p;
    }
}
long long sum(int p)
{
    long long ans=0;
    for(int i=p;i>0;i-=lowbit(i)){
        ans+=s1[i]*(p+1)-s2[i];
    }
    return ans;
}
int main()
{
    while(scanf("%d %d",&n,&m)==2){
        memset(s1,0,sizeof(s1));
        memset(s2,0,sizeof(s2));
        for(int i=1;i<=n;i++){
            long long x;
            scanf("%lld",&x);
            updata(i,x);
            updata(i+1,-x);
        }
        while(m--){
            char s[10];
            scanf("%s",s);
            if(s[0]=='C'){
                int a,b;
                long long c;
                scanf("%d %d %lld",&a,&b,&c);
                updata(a,c);
                updata(b+1,-c);
            }
            else{
                int a,b;
                scanf("%d %d",&a,&b);
                printf("%lld\n",sum(b)-sum(a-1));
            }
        }
    }
    return 0;
}

 

 

4.二维线段树

 单点更新 区间查询

   题目链接

#include<bits/stdc++.h>

using namespace std;
int n,m;
const int N=5000;
long long s[N][N];

int lowbit(int x)
{
    return x&(-x);
}

void updata(int x,int y,int z)
{
    for(int i=x;i<=n;i+=lowbit(i)){
        for(int j=y;j<=m;j+=lowbit(j)){
            s[i][j]+=z;
        }
    }
}

long long sum(int x,int y)
{
    long long res=0;
    for(int i=x;i>0;i-=lowbit(i)){
        for(int j=y;j>0;j-=lowbit(j)){
            res+=s[i][j];
        }
    }
    return res;
}
int main()
{
    memset(s,0,sizeof(s));
    scanf("%d %d",&n,&m);
    int k;
    while(scanf("%d",&k)==1){
        if(k==1){
            int x,y,z;
            scanf("%d %d %d",&x,&y,&z);
            updata(x,y,z);
        }
        else{
            int x1,y1,x2,y2;
            scanf("%d %d %d %d",&x1,&y1,&x2,&y2);
            printf("%lld\n",sum(x2,y2)+sum(x1-1,y1-1)-sum(x1-1,y2)-sum(x2,y1-1));
        }
    }

    return 0;
}

 

 区间修改 单点查询

题目链接

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>

using namespace std;
const int N=1e3+10;
int s[N][N];
int n;
int lowbit(int x)
{
    return x&(-x);
}
void updata(int x,int y,int z)
{
    for(int i=x;i<=n;i+=lowbit(i)){
        for(int j=y;j<=n;j+=lowbit(j)){
            s[i][j]+=z;
        }
    }
}

int sum(int x,int y)
{
    int res=0;
    for(int i=x;i>0;i-=lowbit(i)){
        for(int j=y;j>0;j-=lowbit(j)){
            res+=s[i][j];
        }
    }
    return res;
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--){
        memset(s,0,sizeof(s));
        int m;
        scanf("%d %d",&n,&m);
        while(m--){
            char t[3];
            scanf("%s",t);
            if(t[0]=='C'){
                int x1,y1,x2,y2;
                scanf("%d %d %d %d",&x1,&y1,&x2,&y2);
                updata(x1,y1,1);
                updata(x2+1,y2+1,1);
                updata(x2+1,y1,-1);
                updata(x1,y2+1,-1);
            }
            else{
                int x,y;
                scanf("%d %d",&x,&y);
                printf("%d\n",sum(x,y)%2);
            }
        }
        if(T) printf("\n");
    }

    return 0;
}

 

区间更新 区间查询

题目链接

#include<bits/stdc++.h>

using namespace std;
const int N=2100;
long long s1[N][N],s2[N][N],s3[N][N],s4[N][N];
int n,m;
int lowbit(int x)
{
    return x&(-x);
}

void updata(int x,int y,long long z)
{
    for(int i=x;i<=n;i+=lowbit(i)){
        for(int j=y;j<=n;j+=lowbit(j)){
            s1[i][j]+=z;
            s2[i][j]+=x*z;
            s3[i][j]+=y*z;
            s4[i][j]+=x*y*z;
        }
    }
}
long long sum(int x,int y)
{
    long long res=0;
    for(int i=x;i>0;i-=lowbit(i)){
        for(int j=y;j>0;j-=lowbit(j)){
            res+=(x+1)*(y+1)*s1[i][j]-(y+1)*s2[i][j]-(x+1)*s3[i][j]+s4[i][j];
        }
    }
    return res;
}
int main()
{
    while(scanf("%d %d",&n,&m)==2){
        memset(s1,0,sizeof(s1));
        memset(s2,0,sizeof(s2));
        memset(s3,0,sizeof(s3));
        memset(s4,0,sizeof(s4));
        int k;
        while(scanf("%d",&k)==1){
            if(k==1){
                int a,b,c,d;
                long long x;
                scanf("%d %d %d %d %lld",&a,&b,&c,&d,&x);
                updata(a,b,x);
                updata(c+1,b,-x);
                updata(a,d+1,-x);
                updata(c+1,d+1,x);
            }
            else{
                int x1,y1,x2,y2;
                scanf("%d %d %d %d",&x1,&y1,&x2,&y2);
                printf("%lld\n",sum(x2,y2)-sum(x1-1,y2)-sum(x2,y1-1)+sum(x1-1,y1-1));
            }
        }
    }
    return 0;
}

 

posted @ 2018-12-26 15:04  12-num  阅读(208)  评论(0编辑  收藏  举报