給出n個數,問區間[l,r]中有多少不同的數。
經典題。
可以離線+樹狀陣列,離線儲存查詢,按照r排序,用last陣列儲存每個數最接近當前詢問r的位置。
也可以主席樹,從右到左建樹,pos儲存每個數字的當前最左位置,每次在新版本的線段樹中在當前位置+1,然後把舊版本中該樹的位置-1.
離線+樹狀陣列:
#include
using
namespace
std;
const
int maxn = 1e6 + 10;
int n, q;
int bit[maxn];
void add(int x, int y)
}int sum(int x)
return res;
}struct node
} que[maxn];
int last[maxn], a[maxn], ans[maxn];
int main()
sort (que + 1, que + 1 + q);
for (int i = 1, j = 1; i <= q; i++)
ans[que[i].id] = sum(que[i].r) - sum(que[i].l - 1);
}for (int i = 1; i <= q; i++)
printf("%d\n", ans[i]);
return
0;}
主席樹:
#include
using
namespace
std;
const
int maxn = 33333;
struct node ns[maxn * 40];
int rt[maxn * 2], ct;
void cpy(int& now, int old)
void build(int& now, int l, int r)
void update(int& now, int old, int l, int r, int x, int y)
int m = (l + r) >> 1;
if (x <= m) update(ns[now].ls, ns[old].ls, l, m, x, y);
else update(ns[now].rs, ns[old].rs, m + 1, r, x, y);
ns[now].sum = ns[ns[now].ls].sum + ns[ns[now].rs].sum;
}int query(int now, int old, int l, int r, int l, int r)
int pos[1000005], a[maxn];
int main()
int q;
scanf("%d", &q);
while (q--)
return
0;}
區間的關係的計數 HDU 4638 離線 樹狀陣列
題目大意 給你n個人,每個人都有乙個id,有m個詢問,每次詢問乙個區間 l,r 問該區間內部有多少的id是連續的 單獨的也算是乙個 思路 做了那麼多離線 樹狀陣列的題目,感覺這種東西就是乙個模板了,23333,反正都是定義右區間的。這題的關鍵難度就是如何定義id是連續的呢。我們每次往區間裡面放乙個數...
hdu 3333 離線 樹狀陣列
題目 題意 求乙個區間內不重複數字的和,例如1 1 1 3,區間 1,4 的和為4。分析 我們考慮每個查詢 l,r 現在要求的是這個區間裡不通數的和,所以我們在從左掃到右的過程中,可以用乙個資料結構儲存已經得到的不同的數,到右端點後,然後對區間裡不同的數求和,這樣就可以得到答案了。資料結構可以採用樹...
Binary Indexed Tree 樹狀陣列
做leetcode 做到meetingroomii的時候我知道不用線段樹或者樹狀陣列是不太好搞了。還是來學習一下吧。樹狀陣列算是線段樹的一種特殊情況 子集 所以樹狀陣列能解決的問題線段樹一定能做,但線段樹能做的樹狀陣列不一定能做。對乙個陣列進行如下操作 update i1,i2,operation ...