HDU 4638 Group 樹狀陣列

2022-05-29 07:30:12 字數 1227 閱讀 5622

詢問一段區間裡的數能組成多少段連續的數。先考慮從左往右乙個數乙個數新增,考慮當前新增了i - 1個數的答案是x,那麼可以看出新增完i個數後的答案是根據a[i]-1和a[i]+1是否已經新增而定的:如果a[i]-1或者a[i]+1已經新增乙個,則段數不變,如果都沒新增則段數加1,如果都新增了則段數減1。設v[i]為加入第i個數後的改變量,那麼加到第x數時的段數就是sum (1<=i<=x}。當然,若刪除某個數,那麼這個數兩端的數的改變量也會跟著改變,這樣一段區間的數構成的段數就還是他們的v值的和。將詢問離線處理,按左端點排序後掃瞄一遍,左邊刪除,右邊插入,查詢就是求區間和。

區間和用線段樹或者樹狀陣列維護都可以。當然本題自然是樹狀陣列最好了~空間少,常數小,還好寫。藉此也學了一下樹狀陣列。很讚啊!倍增、分割思想,不到十行的**,嘖嘖~

#include #include #include #include #include #include #include #define mid(x,y) ((x+y)/2)

#define mem(a,b) memset(a,b,sizeof(a))

using namespace std;

const int maxn = 100005;

struct bit

//lowbit(x):求2^q, q是x二進位制最右邊的1的位置.

inline int lowbit(int x)

inline void update(int x, int v)

inline int sum(int x)

}bit;

int a[maxn], pos[maxn];

struct askq[maxn];

bool cmp(ask n1, ask n2)

int res[maxn];

bool is_group[maxn];

int main()

for (int i = 0; i < m; i ++)

sort(q, q+m, cmp);

mem(is_group, false);

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

int st = 1;

for (int i = 0; i < m; i ++)

res[q[i].id] = bit.sum(q[i].r) - bit.sum(q[i].l-1);

}for (int i = 0; i < m; i ++)

}return 0;

}

hdu4638 Group(樹狀陣列)

題目大意 給乙個1 n的排列,然後詢問 x,y 區間中有多少個連續的段。如給乙個3 1 2 5 4,查詢是2 4,那麼就是問1 2 5中有多少個連續的串,一共有兩個串,1 2為乙個串,5為乙個串 若查詢是2 5,則問的是1 2 5 4中有多少個連續的串,一共有兩個串,1 2為乙個串,4 5 為乙個串...

hdu 4638 Group 樹狀陣列

題意 找到區間裡有多少組連續數字串 分析 思路 顯然,我們要使得value最大,就要盡量將連續的id分在一組,所以問題轉化為求乙個區間中連續id區間的個數。我們從左往右掃瞄,依次考慮右端點為i的詢問,設dp l 為區間 l,i 的連續區間個數,po i 為i出現的位置,若還未出現,則為0,設我們當前...

Hdu 4638 Group 離線 樹狀陣列

題目大意 給你1 n的任意全排列,詢問q次,每次詢問區間 l r 內的組數,組數的定義為 在乙個連續區間中,可以把區間中的數任意分成幾組,每組的所有數必須連續,比如 7 5 8的組數為2,即7,8和5。解題思路 先假設每個數都是一組,然後查詢和他相鄰的兩個數是否在此之前出現過,如果出現則 出現的位置...