zoukankan      html  css  js  c++  java
  • 树状数组的基本用法(板子)

    写这篇博客,为了方便自己后续复制粘贴板子; 

    HDU 1166

    题意:单点更新,区间查询

     1 #include <cstdio>
     2 #include <iostream>
     3 #include <cstring>
     4 using namespace std;
     5 
     6 #define lowbit(x) ((x)&-(x))
     7 typedef long long ll;
     8 const int maxn=5e5+5;
     9 int n, q, a[maxn], c[maxn];
    10 
    11 void add(int x, int val)
    12 {
    13     while(x<=n)
    14     {
    15         c[x]+=val;
    16         x+=lowbit(x);
    17     }
    18 }
    19 
    20 int ask(int x)
    21 {
    22     int ans=0;
    23     while(x>0)
    24     {
    25         ans+=c[x];
    26         x-=lowbit(x);
    27     }
    28     return ans;
    29 }
    30 
    31 int main()
    32 {
    33     //freopen("in.txt", "r", stdin);
    34     //ios::sync_with_stdio(false);
    35     int T, kase=0; cin>>T;
    36     while(T--)
    37     {
    38         cin>>n;
    39         memset(c, 0, sizeof(c));
    40         for(int i=1; i<=n; i++)
    41         {
    42             int x; cin>>x;
    43             add(i, x);
    44         }
    45 
    46         printf("Case %d:
    ", ++kase);
    47         char s[10];
    48         while(scanf("%s", s+1), s[1]!='E')
    49         {
    50             int x,y; cin>>x>>y;
    51             if(s[1]=='Q')
    52                 printf("%d
    ", ask(y)-ask(x-1));
    53             else if(s[1]=='A')
    54                 add(x, y);
    55             else
    56                 add(x, -y);
    57         }
    58     }
    59     return 0;
    60 }
    View Code

    HDU 1754

    题意:区间查询(最大值),单点更新; 

    不过好像树状数组在维护最大值好像没有线段树快,这个看看就行了,遇到了还是写线段树吧!

     1 #include <cstdio>
     2 #include <iostream>
     3 #include <cstring>
     4 using namespace std;
     5 
     6 #define lowbit(x) ((x)&-(x))
     7 typedef long long ll;
     8 const int maxn=5e5+5;
     9 int n, q, a[maxn], c[maxn];
    10 
    11 void add(int x, int val)
    12 {
    13     while(x<=n)
    14     {
    15         c[x]=val;
    16         for(int i=1; i<lowbit(x); i<<=1)
    17             c[x]=max(c[x], c[x-i]);
    18         x+=lowbit(x);
    19     }
    20 }
    21 
    22 int ask(int l, int r)
    23 {
    24     int ans=0;
    25     while(l<=r)
    26     {
    27         ans=max(ans, a[r]);   ///注意这一行是和a数组比的
    28         r--;
    29         for( ; r-l>=lowbit(r); r-=lowbit(r))
    30             ans=max(ans, c[r]);
    31     }
    32     return ans;
    33 }
    34 
    35 int main()
    36 {
    37     //freopen("in.txt", "r", stdin);
    38     ios::sync_with_stdio(false);
    39     while(cin>>n>>q)
    40     {
    41         for(int i=1; i<=n; i++)
    42         {
    43             cin>>a[i];
    44             add(i, a[i]);
    45         }
    46 
    47         while(q--)
    48         {
    49             char cmd; int x, y;
    50             cin>>cmd>>x>>y;
    51             if(cmd=='Q')
    52                 printf("%d
    ", ask(x,y));
    53             else
    54             {
    55                 a[x]=y;
    56                 add(x, y);
    57             }
    58         }
    59     }
    60     return 0;
    61 }
    View Code

    POJ 3468 

    题意:区间查询,区间更新; 

     1 #include <cstdio>
     2 #include <iostream>
     3 #include <cstring>
     4 using namespace std;
     5 
     6 #define lowbit(x) ((x)&-(x))
     7 #define _rep(x,y) for(int i=(x); i<=(y); i++)
     8 typedef long long ll;
     9 const int maxn=1e5+5;
    10 ll sum1[maxn], sum2[maxn], sum[maxn];
    11 int n, q, a[maxn], c[maxn];
    12 
    13 void add(int x, int val)
    14 {
    15     int i=x;
    16     while(i<=n)
    17     {
    18         sum1[i]+=val;
    19         sum2[i]+=val*x;
    20         i+=lowbit(i);
    21     }
    22 }
    23 
    24 void range_add(int l, int r, int x)
    25 {
    26     add(l, x); add(r+1, -x);
    27 }
    28 
    29 ll ask(int x)
    30 {
    31     ll ans=0; int i=x;
    32     while(i>0)
    33     {
    34         ans+=(x+1)*sum1[i]-sum2[i];
    35         i-=lowbit(i);
    36     }
    37     return ans;
    38 }
    39 
    40 ll range_ask(int l, int r)
    41 {
    42     return ask(r)-ask(l-1);
    43 }
    44 
    45 
    46 int main()
    47 {
    48     //freopen("in.txt", "r", stdin); 
    49     ios::sync_with_stdio(false);
    50     cin>>n>>q;
    51     _rep(1,n){
    52         cin>>a[i];
    53         sum[i]=sum[i-1]+a[i];
    54     }
    55     while(q--)
    56     {
    57         char cmd; int x,y;
    58         cin>>cmd>>x>>y;
    59         if(cmd=='Q')
    60             printf("%I64d
    ", sum[y]-sum[x-1]+range_ask(x,y));
    61         else
    62         {
    63             int z; cin>>z;
    64             range_add(x, y, z);
    65         }
    66     }
    67     return 0;
    68 }
    View Code

    HDU 1698 (未解决)

    题意:区间覆盖(不会),区间查询

  • 相关阅读:
    XML 的学习笔记3
    XML 的学习笔记2
    XML 的学习笔记1
    Tomcat 学习笔记2
    Tomcat 学习笔记1
    sol
    sol
    0、安装Ionic2
    ionic2 目录
    6、Angular Route 路由
  • 原文地址:https://www.cnblogs.com/Yokel062/p/10804764.html
Copyright © 2011-2022 走看看