程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 樹狀數組——poj 3928

樹狀數組——poj 3928

編輯:C++入門知識

樹狀數組是一個思想很巧妙的算法。

樹狀數組主要是求動態連續和、查詢等問題

先理解lowbit(i) , i是指數組中的位置(從1開始) , lowbit(i) 是i的二進制表達式中最右邊的1所對應的值 , 也就是說lowbit(i) = i&(-i)

假設a[i]存儲的是樹 , c[i]是表示a[i] + a[i-1].......+a[i-lowbit(i)] , 那麼這時 , 我們要求數組a中前 i 個數和 (a[i]+a[i-1].....+a[1]),我們只需要這麼求:

int sum_tree_shuzu(int i)
{
    int sum = 0;
    while(i>0)
    {
        sum += c[i];
        i -= lowbit(i);
    }
    return sum;
}

對於這點大家可以驗證一下。

當我們改變了數組a中的某個數時 , 應該怎麼來改變數組c中的值呢。

我們假設改變:a[i] = a[i]+d;

這時我們只需要改變數組 c 中和 a[i] 相關的值。

void add_tree_shuzu(int i , int d)
{
    while(i <= n)
    {
        b[i] += d;
        i += lowbit(i);
    }
}

下面說一下例題:poj 3928

這個題目的關鍵點:

1、每個隊員的能力值都不一樣 , 就說沒有想等的能力值

2、我們只需要對裁判遍歷。

代碼:

#include 
#include 
#include 
#include 
using namespace std;

int a[20010] , b[20010] , c[20010];
int n;

bool cmp(int i , int j)
{
    return a[i] <= a[j];
}

inline int lowbit(int y)
{
    return y&(-y);
}

int sum_tree_shuzu(int y)
{
    int sum = 0;
    while(y>0)
    {
        sum += b[y];
        y -= lowbit(y);
    }
    return sum;
}

void add_tree_shuzu(int i , int x)
{
    while(i <= n)
    {
        b[i] += x;
        i += lowbit(i);
    }
}

int main()
{
    int t;
    scanf("%d" , &t);
    while(t--)
    {
        scanf("%d" , &n);
        int i , x , j;
        memset(b , 0 , sizeof(b));
        for(i = 1; i <= n; i++)
        {
            scanf("%d" , &a[i]);
            c[i] = i;
        }
        
        sort(c+1 , c+n+1, cmp); //對隊員的能力值進行排序,
        add_tree_shuzu(c[1] , 1);
        __int64 sum = 0;
        for(i = 2; i < n; i++)
        {
            x = sum_tree_shuzu(c[i]);
            sum += x*(n-c[i]-i+x+1) + (i-1-x)*(c[i]-1-x);//裁判住在c[i]的位置,那麼有i-1個隊員住在裁判前面,n-i個隊員住在裁判後面
            add_tree_shuzu(c[i] , 1);
        }
        printf("%I64d\n" , sum);
            
    }
    return 0;
}


  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved