zoukankan      html  css  js  c++  java
  • 一维树状数组入门

    个人觉得非常棒的博客:https://www.cnblogs.com/xenny/p/9739600.html

    第一类:单点更新,区间查询

        例题:http://acm.hdu.edu.cn/showproblem.php?pid=1166

         AC代码:

     1 /* */
     2 # include <iostream>
     3 # include <cstdio>
     4 # include <cstring>
     5 # include <string>
     6 # include <cstdlib>
     7 # include <queue>
     8 # include <stack>
     9 # include <vector>
    10 # include <map>
    11 # include <set>
    12 # include <cmath>
    13 # include <bitset>
    14 # include <functional>
    15 using namespace std;
    16 
    17 int n, m;
    18 int a[50005], c[50005];///对应原数组和树状数组
    19 int lowbit(int x)
    20 {
    21     return x&(-x);///当x为0时结果为0,当x为奇数时,结果为1;
    22     ///当x为偶数时,结果为x中2的最大次方的因子
    23     ///2^k=i&(-i)
    24 }
    25 
    26 void updata(int i, int k)///在第i个位置上加上k
    27 {
    28     while( i<=n )///a[i]包含于c[i+2^k], c[i+2^k+2^k], c[i+2^k+2^k+2^k], ,,,
    29     {
    30         c[i] += k;
    31         i += lowbit(i);
    32     }
    33 }
    34 
    35 int getsum(int i)
    36 {
    37     int res=0;
    38     while( i>0 )
    39     {
    40         res += c[i];
    41         i -= lowbit(i);
    42     }
    43     return res;
    44 }
    45 
    46 int main()
    47 {
    48     int t;
    49     cin>>t;
    50     for(int tot=1; tot<=t; tot++ )
    51     {
    52         cout<<"Case "<<tot<<":"<<endl;
    53         memset(a, 0, sizeof(a));
    54         memset(c, 0, sizeof(c));
    55         cin>>n;
    56         for(int i=1; i<=n; i++ )
    57         {
    58             cin>>a[i];
    59             updata(i, a[i]);
    60         }
    61 
    62         string s;
    63         int x, y;
    64         while( cin>>s && s[0]!='E' )
    65         {
    66             cin>>x>>y;
    67             if( s[0]=='Q')
    68             {
    69                 int sum=getsum(y)-getsum(x-1);
    70                 cout<<sum<<endl;
    71             }
    72             else if( s[0]=='A' )
    73             {
    74                 updata(x, y);
    75             }
    76             else if( s[0]=='S' )
    77             {
    78                 updata(x, -y);
    79             }
    80         }
    81     }
    82     return 0;
    83 }
    View Code

    第二类:区间修改,单点查询

        例题:http://acm.hdu.edu.cn/showproblem.php?pid=1556

        AC代码:

     1 /* 一位数状数组:区间修改,单点查询 */
     2 # include <iostream>
     3 # include <stdio.h>
     4 # include <string.h>
     5 # include <string>
     6 # include <algorithm>
     7 # include <cmath>
     8 # include <cstdlib>
     9 # include <cctype>
    10 # include <deque>
    11 # include <climits>
    12 # include <queue>
    13 # include <stack>
    14 # include <set>
    15 # include <bitset>
    16 # include <list>
    17 # include <map>
    18 using namespace std;
    19 
    20 # define LL long long
    21 # define lowbit(x)(x&(-x))
    22 # define gcd(a, b) __gcd(a, b)
    23 # define INF 0x3f3f3f3f
    24 # define N 100010
    25 
    26 int c[N];///树状数组不一定是求和
    27 
    28 void updata(int x, int val)
    29 {
    30     while( x<=N )
    31     {
    32         c[x] += val;
    33         x += lowbit(x);
    34     }
    35 }
    36 
    37 int getsum(int x)
    38 {
    39     int res=0;
    40     while( x>0 )
    41     {
    42         res += c[x];
    43         x -= lowbit(x);
    44     }
    45     return res;
    46 }
    47 
    48 int main()
    49 {
    50     int n, x, y, i;
    51     while( ~ scanf("%d", &n) && n )
    52     {
    53         memset(c, 0, sizeof(c));
    54         for(i=0; i<n; i++ )
    55         {
    56             scanf("%d %d", &x, &y);
    57             updata(x, 1);
    58             updata(y+1, -1);
    59         }
    60 
    61         for(i=1; i<=n-1; i++ )
    62             printf("%d ", getsum(i));
    63         printf("%d
    ", getsum(n));
    64     }
    65     return 0;
    66 }
    View Code

    第三类:区间修改,区间查询

        例题:http://poj.org/problem?id=3468

         AC代码:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <algorithm>
     5 using namespace std;
     6 typedef long long ll;
     7 const int maxn=100010;
     8 ll sum1[maxn];
     9 ll sum2[maxn];
    10 ll a[maxn];
    11 int n,m;
    12 int lowbit(int i){
    13     return i&(-i);
    14 }
    15 
    16 void updata(int i,ll k){
    17     int x=i;
    18     while(i<=n){
    19         sum1[i]+=k;
    20         sum2[i]+=k*(x-1);
    21         i+=lowbit(i);
    22     }
    23 }
    24 
    25 ll getsum(int i){
    26     ll res=0;
    27     int x=i;
    28     while(i>0){
    29         res+=x*sum1[i]-sum2[i];
    30         i-=lowbit(i);
    31     }
    32     return res;
    33 }
    34 
    35 int main()
    36 {
    37     while(~scanf("%d%d",&n,&m)){
    38         memset(sum1,0,sizeof(sum1));
    39         memset(sum2,0,sizeof(sum2));
    40         for(int i=1;i<=n;i++){
    41             scanf("%lld",&a[i]);
    42             updata(i,a[i]-a[i-1]);
    43         }
    44         char s[10];
    45         while( m-- ){
    46             scanf("%s",s);
    47             if( s[0]=='C'){
    48                 int x,y,c;
    49                 scanf("%d%d%d",&x,&y,&c);
    50                 updata(x,c);
    51                 updata(y+1,-c);
    52             }
    53             else{
    54                 int x,y;
    55                 scanf("%d%d",&x,&y);
    56                 ll sum=getsum(y)-getsum(x-1);
    57                 cout<<sum<<endl;
    58             }
    59         }
    60     }
    61     return 0;
    62 }
    View Code
  • 相关阅读:
    大型网站核心架构因素
    大型网站架构模式
    博客中的文章归档是如何实现的
    Caused by: java.sql.SQLException: Value '0000-00-00 00:00:00' can not be represented as java.sql.Timestamp
    git分支开发的好处
    layui之日期和时间组件
    vue-electron脚手架
    springboot1.5.4 配置druid1.1.0(使用druid-spring-boot-starter)
    Node.js读取文件内容并返回值(非异步)
    C# ftp ListFilesOnServer
  • 原文地址:https://www.cnblogs.com/wsy107316/p/11323605.html
Copyright © 2011-2022 走看看