hdu 3333 離線 樹狀陣列

2021-07-22 16:52:31 字數 1317 閱讀 2098

題目:

題意:

求乙個區間內不重複數字的和,例如1 1 1 3,區間[1,4]的和為4。

分析:

我們考慮每個查詢[l,r],現在要求的是這個區間裡不通數的和,所以我們在從左掃到右的過程中,可以用乙個資料結構儲存已經得到的不同的數,到右端點後,然後對區間裡不同的數求和,這樣就可以得到答案了。

資料結構可以採用樹狀陣列,那麼我們是不是對每個查詢區間都掃一遍呢?,顯然是不行的,時間複雜度太大,我們只掃一遍即可!因為我們已經用樹狀陣列儲存了到i點之前所有的不同的數,當我們掃到某個查詢區間的右端點時,我們只需要查詢[l,r]這段區間即可。

當然檢視是否掃到了某個右區間端點,可以先按右端點排序,或者直接用vector儲存右端點相同的區間。

**:

#include 

#include

#include

#include

#include

#include

#include

#include

#include

#include

using

namespace

std;

typedef

long

long ll;

const

int n = 1e5 + 9;

int a[n], n, q;

ll c[n], ans[n];

int lowbit (int x)

void update (int x, int val)

ll getsum (int x)

ll query (int l, int r)

struct node ;

vector

inv[n];

mapmmap;

int main() );

}memset (c, 0, sizeof (c) );

mmap.clear();

for (int i = 1; i <= n; i++)

for (int i = 1; i <= q; i++)

printf ("%lld\n", ans[i]);

}return0;}

/*sample input23

1 1 4

21 2

2 35

1 1 2 1 3

31 5

2 43 5

sample output15

636*/

hdu 3333 樹狀陣列

此題與3743相仿,但本題資料較大,需要用到離散化。如何去掉重複元素呢?採用離線演算法 首先將詢問按右端點從小到大排序,離線處理時,記錄每個元素所在位置,遇到重複元素時,從它之前出現的位置減去這個元素,這樣就是的每個元素總是出現在最後。include include include include ...

hdu 3333 樹狀陣列

思路 定義乙個map容器用來記錄數ai上次出現的位置。將查詢區間按右邊界公升序進行排序,當插入第i個數ai時,pre ai 1 i的區間就會多乙個不同的數,其值就是ai,那麼可以用update pre ai 1,ai 來儲存,但又不能影響i之後的位置,故用update i,ai 來消除。每次對於右邊...

HDU 3333 離線線段樹

線段樹 給定乙個序列,求區間出現的數的數值和,若有多個,只計算一次 先離散化存數資料 對詢問區間按右節點排序,這樣我們每次維護的都是從前到當前位置,保證其重複元素不累加 跟新節點,對於之前出現過的刪除,並在新位置新增 然後查詢即可 include iostream include algorithm...