zoukankan      html  css  js  c++  java
  • wenbao与树状数组(BIT)

     经典入门题,敌兵布阵

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

     1 #include <iostream>
     2 #include <stdio.h>
     3 #include <string.h>
     4 using namespace std;
     5 
     6 int n,aa[50005],cc[50005];
     7 
     8 int lowbit(int x){
     9     return x&(-x);
    10 }
    11 
    12 void add(int x,int y){
    13     while(x<=n){
    14         cc[x]+=y;
    15         x+=lowbit(x);
    16     }
    17 }
    18 
    19 int sum(int x){
    20     int s=0;
    21     while(x>0){
    22         s+=cc[x];
    23         x-=lowbit(x);
    24     }
    25     return s;
    26 }
    27 
    28 int main(){
    29     int t,countn=1;
    30     char str[20];
    31     scanf("%d",&t);
    32     while(t--){
    33         memset(aa,0,sizeof(aa));
    34         memset(cc,0,sizeof(cc));
    35         scanf("%d",&n);
    36         for(int i=1;i<=n;i++){
    37             scanf("%d",&aa[i]);
    38             add(i,aa[i]);
    39         }
    40         printf("Case %d:
    ",countn);
    41         while(~scanf("%s",str)){
    42             if(str[0]=='E')
    43                 break;
    44             if(str[0]=='A'){
    45                 int a,b;
    46                 scanf("%d%d",&a,&b);
    47                 add(a,b);
    48             }
    49             if(str[0]=='Q'){
    50                 int a,b;
    51                 scanf("%d%d",&a,&b);
    52                 printf("%d
    ",sum(b)-sum(a-1));
    53             }
    54             if(str[0]=='S'){
    55                 int a,b;
    56                 scanf("%d%d",&a,&b);
    57                 add(a,-b);
    58             }
    59         }
    60         countn++;
    61     }
    62     return 0;
    63 }

     -----------------------------------------------------------------------------------------

    http://acm.hdu.edu.cn/showproblem.php?pid=4417

    给定n个高度,有m个询问LR之间小于等于H的个数

     1 #include <iostream>
     2 #include <algorithm>
     3 #include <string.h>
     4 using namespace std;
     5 #define bt(x) x&(-x)
     6 const int maxn = 1e5+10;
     7 int n, m, a[maxn], sum[maxn];
     8 struct Node{
     9     int x, y;
    10     bool friend operator < (Node a, Node b){
    11         return a.x < b.x;
    12     }
    13 }T[maxn];
    14 struct Node2{
    15     int l, r, x, y;
    16     bool friend operator < (Node2 a, Node2 b){
    17         return a.x < b.x;
    18     }
    19 }TT[maxn];
    20 void ad(int x, int xx){
    21     while(x <= n){
    22         a[x] += xx;
    23         x += bt(x);
    24     }
    25 }
    26 int q(int x){
    27     int sum = 0;
    28     while(x){
    29         sum += a[x];
    30         x -= bt(x);
    31     }
    32     return sum;
    33 }
    34 int main(){
    35     int t;
    36     scanf("%d", &t);
    37     for(int tt = 1; tt <= t; ++tt){
    38         scanf("%d%d", &n, &m);
    39         a[0] = 0;
    40         for(int i = 1; i <= n; ++i){
    41             a[i] = 0;
    42             scanf("%d", &T[i].x);
    43             T[i].y = i;
    44         }
    45         sort(T+1, T+n+1);
    46         for(int i = 1; i <= m; ++i){
    47             scanf("%d%d%d", &TT[i].l, &TT[i].r, &TT[i].x);
    48             TT[i].y = i;
    49         }
    50         sort(TT+1, TT+m+1);
    51         int num = 1;
    52         printf("Case %d:
    ", tt);
    53         for(int i = 1; i <= m; ++i){
    54             int xx = TT[i].x;
    55             while(num <= n && xx >= T[num].x){
    56                 int xxx = T[num].y; 
    57                 ad(xxx, 1);
    58                 num ++;
    59             }
    60             sum[TT[i].y] = q(TT[i].r+1) - q(TT[i].l);
    61         }
    62         for(int i = 1; i <= m; ++i){
    63             printf("%d
    ", sum[i]);
    64         }
    65     }
    66     return 0;
    67 }

     -----------------------------------------------------------------------------------------

     https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&category=26&page=show_problem&problem=2330

    一条街上住着n个乒乓球爱好者,有不同的能力值,每场比赛需要3个人(两名选手一名裁判)要求裁判住在选手中间并且能力值在两名选手中间,问一共可以组织多少种比赛

     1 #include <iostream>
     2 #include <string.h>
     3 using namespace std;
     4 #define ll long long
     5 #define bt(x) x&(-x)
     6 const int maxn = 1e5+10;;
     7 int t, n, a[maxn], b[maxn], c[maxn], d[maxn];
     8 void add(int x, int y){
     9     while(x < maxn){
    10         d[x] += y;
    11         x += bt(x);
    12     }
    13 }
    14 int q(int x){
    15     int sum = 0;
    16     while(x){
    17         sum += d[x];
    18         x -= bt(x);
    19     }
    20     return sum;
    21 }
    22 int main(){
    23     scanf("%d", &t);
    24     while(t--){
    25         scanf("%d", &n);
    26         memset(d, 0, sizeof(int)*maxn);
    27         for(int i = 1; i <= n; ++i){
    28             scanf("%d", &a[i]);
    29             add(a[i], 1);
    30             b[i] = q(a[i]-1);
    31         }
    32         memset(d, 0, sizeof(int)*maxn);
    33         for(int i = n; i >= 1; --i){
    34             add(a[i], 1);
    35             c[i] = q(a[i]-1);
    36         }
    37         ll sum = 0;
    38         for(int i = 1; i <= n; ++i){
    39             sum = sum + (ll)b[i]*(n-i-c[i]) + (ll)c[i]*(i-b[i]-1);
    40         }
    41         printf("%lld
    ", sum);
    42     }
    43     return 0;
    44 }

      -----------------------------------------------------------------------------------------

    http://poj.org/problem?id=2828

    神奇的BIT

    find函数,利用二进制来快速求出第k大数,只需log复杂度

     1 #include <iostream>
     2 #include <string.h>
     3 using namespace std;
     4 #define bt(x) x&(-x)
     5 const int maxn = 200009;
     6 int n, a[maxn], b[maxn], sum[maxn], c[maxn];
     7 void add(int x, int y){
     8     while(x <= n){
     9         sum[x] += y;
    10         x += bt(x);
    11     }
    12 }
    13 int f(int x){
    14     int xx = 0, yy = 0;
    15     for(int i = 20; i >= 0; --i){
    16         xx += 1<<i;
    17         if(xx > n || yy + sum[xx] >= x){
    18             xx -= 1<<i;
    19         }else{
    20             yy += sum[xx];
    21         }
    22     }
    23     return xx+1;
    24 }
    25 int main(){
    26     while(~scanf("%d", &n)){
    27         memset(sum, 0, sizeof(int)*maxn);
    28         for(int i = 1; i <= n; ++i){
    29             scanf("%d%d", &a[i], &b[i]);
    30             add(i, 1);
    31         }
    32         for(int i = n; i >= 1; --i){
    33             int xx = f(a[i]+1);
    34             c[xx] = b[i];
    35             add(xx, -1);
    36         }
    37         for(int i = 1; i <= n; ++i){
    38             printf("%d%c", c[i], i == n ? '
    ' : ' ');
    39         }
    40     }
    41     return 0;
    42 }

      -----------------------------------------------------------------------------------------

    区间更新

     推荐博客http://www.cnblogs.com/lcf-2000/p/5866170.html

    自从有了它之后。。什么?线段树是什么?

     1 #include <iostream>
     2 using namespace std;
     3 #define ll long long
     4 #define bt(x) x&-x
     5 const int maxn = 100009;
     6 int n, m, x, y;
     7 ll xx, c1[maxn], c2[maxn];
     8 void add(int x, ll y){
     9     for(int i = x; i <= n; i += bt(i)) c1[i] += y, c2[i] += x*y;
    10 }
    11 ll f(int x){
    12     ll sum = 0;
    13     for(int i = x; i; i -= bt(i)) sum += c1[i]*(x+1) - c2[i];
    14     return sum;
    15 }
    16 int main(){
    17     scanf("%d%d", &n, &m);
    18     for(int i = 1; i <= n; ++i){
    19         scanf("%lld", &xx);
    20         add(i, xx), add(i+1, -xx);
    21     }
    22     char str[3];
    23     for(int i = 0; i < m; ++i){
    24         scanf("%s", str);
    25         if(str[0] == 'Q'){
    26             scanf("%d%d", &x, &y);
    27             printf("%lld
    ", f(y)-f(x-1));
    28         }else{
    29             scanf("%d%d%lld", &x, &y, &xx);
    30             add(x, xx), add(y+1, -xx);
    31         }
    32     }
    33     return 0;
    34 }

      -----------------------------------------------------------------------------------------

    https://loj.ac/problem/524

    如果没有X直接判断逆序对奇偶性,否则判断X个数的奇偶性(1要特判)

    因为最后一个放的人肯定可以放成胜态

     1 #include <iostream>
     2 #include <map>
     3 #include <string.h>
     4 #include <algorithm>
     5 using namespace std;
     6 
     7 const int M = 1e9+5;
     8 const int maxn = 100009;
     9 char str[222];
    10 int a[maxn], n, numx, numi = 1, b[maxn], m[maxn];
    11 
    12 void add(int x){
    13     while(x <= numi){
    14         m[x] += 1;
    15         x += (x&-x);
    16     }
    17 }
    18 
    19 int f(int x){
    20     int sum = 0;
    21     while(x){
    22         sum += m[x];
    23         x -= (x&-x);
    24     }
    25     return sum;
    26 }
    27 
    28 int q(){
    29     int num = 0;
    30     for(int i = 1; i < numi; ++i){
    31         num += f(b[i]);
    32         add(b[i]);
    33     }
    34     return num;
    35 }
    36 
    37 int main(){
    38     scanf("%d", &n);
    39     for(int i = 0; i < n; ++i){
    40         scanf("%s", str);
    41         if(str[0] == 'X') numx ++;
    42         else a[numi++] = atoi(str);
    43     }
    44     if(!numx){
    45         for(int i = 1; i < numi; ++i) b[i] = i;
    46         sort(b+1, b+numi, [](int x, int y){
    47             return a[x] < a[y];
    48         });
    49         if(q()&1) printf("W
    ");
    50         else printf("L
    ");
    51         return 0;
    52     }
    53     if(n == 1){
    54         return printf("L
    "), 0;
    55     }
    56     if(numx&1) printf("W
    ");
    57     else printf("L
    ");
    58     return 0;
    59 }

      -----------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------

    只有不断学习才能进步!

  • 相关阅读:
    request
    href="#"
    可展开收起的客服导航。
    JS添加父节点的方法。
    精简漂亮的导航浮动菜单显示特效演示
    竖排导航
    仿新浪微博
    鼠标滑过改变文字
    滚动函数
    一些常用的兼容函数。
  • 原文地址:https://www.cnblogs.com/wenbao/p/5694305.html
Copyright © 2011-2022 走看看