LightOj 1188 樹狀陣列

2021-07-09 12:17:49 字數 1866 閱讀 5976

題意:

給乙個數列(len <= 1e5),數列裡的數(num <= 1e5)。

現有q次詢問(<=1e5),詢問某個區間的不同的數有多少個。

思路:

明顯的樹狀陣列統計,自己寫的時候不太清楚那個樹狀陣列到底應該怎麼維護。有點想用掃瞄線類似的思想,然後離線所有詢問這樣去維護,甚至想到了按照右區間排序。但是到底樹狀陣列應該怎樣維護就不知道了。

題解接著往下。離線所有詢問,按照右端點排序,然後更新樹狀陣列至當前遍歷到詢問的右端點。這樣一來,樹狀陣列裡存的值都是在當前詢問的左邊。那麼現在要去重,記錄對於每個節點上一次出現的地方last[i],當前節點i。那麼對於[last[i],i]這個區間,如果加以詢問時,就會多出i這個點對答案的貢獻,而之前更新last[i]的時候已經對樹狀陣列有所更新。也就是說,需要對last[i]進行相應的update來達到容斥的效果。

再具體一點說,i肯定是在當前詢問中有所貢獻的,為了避免ans = query(r)-query(l-1)小(沒有更新i以後)或者大(l-1在last[i]之前,這樣i對答案貢獻為2而不是正確的1),所以對這個區間[last[i],i]進行操作,使得這個區間內沒有i這個數「存在」。

然後見**。

再補幾句,因為當前詢問的區間的右端點肯定是在r這裡,而我們要排除掉詢問區間中i在詢問區間、last[i]也在詢問區間中的點。所以只要留下最新遍歷到的點就好,大概是這個意思。

原始碼:

#include 

#include

#include

#include

#include

#include

#include

using namespace std;

#define maxn (100000 + 5)

int a[maxn];

intlast[maxn], head[maxn];

int tree[maxn * 4];

int n, q;

void update(int a, int val)

int query(int a)

struct q

que[maxn];

bool cmp(q a, q b)

int res[maxn];

int main()

// for(int i = 1 ; i <= n ; i++) printf("last[%d] = %d\n", i, last[i]);

memset(tree, 0, sizeof(tree));

//for(int i = 1 ; i <= n ; i++) printf("query(%d) = %d\n", i, query(i));

//for(int i = 1 ; i <= n ; i++) printf("%d ", tree[i]);

for(int i = 1 ; i <= q ; i++) scanf("%d

%d", &que[i].l, &que[i].r), que[i].id = i;

sort(que + 1, que + q + 1, cmp);

int rear = 1;

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

res[que[i].id] = query(que[i].r) - query(que[i].l - 1);

//printf("res[%d] = %d\n", que[i].id, res[que[i].id]);

}printf("case %d:\n", cas);

for(int i = 1 ; i <= q ; i++) printf("%d\n", res[i]);

}return

0;}

lightoj 1085 離散化 樹狀陣列

題意 計算乙個序列裡有多少個上公升子串行 思路 先離散化一下,按照值排序,如果相同的就按照座標從大到小排序,這樣就可以避免重複計算。樹狀陣列存的是以a i 結尾的子串行之和 dp a i sigma a i 1 1 ok,還是很簡單的 include using namespace std type...

LightOJ 1085 樹狀陣列 動態規劃

題目鏈結 記 dp i 為以第i個結尾的上公升子串行的個數,可以得到轉移方程 dp i sum 所以求出每乙個 dp i 直接求複雜度 o n 2 自然是不行的。因為只和大小的比較有關係,跟數值本身是無關的,所以先將其離散化。變成1到pos的點。這樣就可以開下乙個樹狀陣列。樹狀陣列可以很方便的求出前...

樹狀陣列1 樹狀陣列入門

仔細看一下,發現tree的每乙個節點的高度並不是隨意的,而是由它轉成二進位制之後末尾連續零的數量決定的,連續零的數量加1,就是高度,例如 3 11 零的數量為0,加1等於1,所以它的高度就是1 6 110 零的數量為1,加1等於2,所以它的高度就是2 8 1000 零的數量為3,加1等於4,所以它的...