日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

[SPOJ DQUERY] D-query(树状数组,离线)

發布時間:2023/12/10 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [SPOJ DQUERY] D-query(树状数组,离线) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目鏈接:https://vjudge.net/problem/SPOJ-DQUERY

題意:給定數列,q次詢問,問區間內不同數字的個數。

可以用主席樹,但是還有更好寫的辦法。

離線存下所有的詢問,按照詢問右端點從小到大排序。

用樹狀數組標記“某個值在區間[1,r]中出現的最后的位置”。這樣可以將r從左向右平移,每一個r更新所有右邊界為r的查詢。

因為某值出現總是盡可能向后,所以這樣可以保證可以被查到。

用一個map來記錄某個值出現的位置,然后移動的時候更新樹狀數組就行了。整體復雜度就是O(n*logn+Q)的。

?

1 #include <bits/stdc++.h> 2 using namespace std; 3 4 typedef struct Event { 5 int l, r, id; 6 }Event; 7 const int maxn = 200100; 8 int n, q, a[maxn]; 9 int bit[maxn]; 10 vector<Event> event; 11 int ret[maxn]; 12 unordered_map<int, int> vis; 13 14 bool cmp(Event a, Event b) { return a.r < b.r; } 15 int lowbit(int x) { return x & (-x); } 16 void add(int i, int v) { for(; i <= n; i+=lowbit(i)) bit[i] += v; } 17 int sum(int i) { int ret = 0; for(; i > 0; i-=lowbit(i)) ret += bit[i]; return ret; } 18 19 int main() { 20 // freopen("in", "r", stdin); 21 int l, r; 22 while(~scanf("%d",&n)) { 23 for(int i = 1; i <= n; i++) scanf("%d", &a[i]); 24 event.clear(); vis.clear(); 25 memset(bit, 0, sizeof(bit)); 26 scanf("%d", &q); 27 for(int i = 1; i <= q; i++) { 28 scanf("%d%d",&l,&r); 29 event.push_back(Event{l,r,i}); 30 } 31 sort(event.begin(), event.end(), cmp); 32 r = 0; 33 for(int i = 1; i <= n; i++) { 34 if(vis.find(a[i]) == vis.end()) { 35 vis[a[i]] = i; 36 add(i, 1); 37 } 38 else { 39 add(vis[a[i]], -1); 40 vis[a[i]] = i; 41 add(i, 1); 42 } 43 while(event[r].r == i) { 44 ret[event[r].id] = sum(event[r].r) - sum(event[r].l-1); 45 r++; 46 } 47 } 48 for(int i = 1; i <= q; i++) printf("%d\n", ret[i]); 49 } 50 return 0; 51 }

?

轉載于:https://www.cnblogs.com/kirai/p/6835080.html

總結

以上是生活随笔為你收集整理的[SPOJ DQUERY] D-query(树状数组,离线)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。