zoukankan      html  css  js  c++  java
  • 树状数组 模板

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

    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
    ",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("
    ");
        }
        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
    ", 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
    ",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
    ",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
    ",sum(x,y)%2);
                }
            }
            if(T) printf("
    ");
        }
    
        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
    ",sum(x2,y2)-sum(x1-1,y2)-sum(x2,y1-1)+sum(x1-1,y1-1));
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    2015年个人记录
    Win10如何新建用户怎么添加新账户
    快速搭建一个本地的FTP服务器
    天气接口
    一张图搞定OAuth2.0
    PHP TS 和 NTS 版本选择
    如何在 Laravel 中使用 SMTP 发送邮件(适用于 163、QQ、Gmail 等)
    Npm vs Yarn 之备忘详单
    浅谈CSRF
    值得看的cookie详解
  • 原文地址:https://www.cnblogs.com/chenchen-12/p/10179204.html
Copyright © 2011-2022 走看看