Necklace(树状数组+离线操作)
生活随笔
收集整理的這篇文章主要介紹了
Necklace(树状数组+离线操作)
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
題目連接:http://acm.hdu.edu.cn/showproblem.php?pid=3874
Necklace
Time Limit: 15000/5000 MS (Java/Others)????Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 3929????Accepted Submission(s): 1296
Now Mery thinks the necklace is too long. She plans to take some continuous part of the necklace to build a new one. She wants to know each of the beautiful value of M continuous parts of the necklace. She will give you M intervals [L,R] (1<=L<=R<=N) and you must tell her F(L,R) of them.
?
Input The first line is T(T<=10), representing the number of test cases.??For each case, the first line is a number N,1 <=N <=50000, indicating the number of the magic balls. The second line contains N non-negative integer numbers not greater 1000000, representing the beautiful value of the N balls. The third line has a number M, 1 <=M <=200000, meaning the nunber of the queries. Each of the next M lines contains L and R, the query.
?
Output For each query, output a line contains an integer number, representing the result of the query.?
Sample Input 2 6 1 2 3 4 3 5 3 1 2 3 5 2 6 6 1 1 1 2 3 5 3 1 1 2 4 3 5?
Sample Output 3 7 14 1 3 6 題意: 求區(qū)間不重復(fù)元素和 題解: 詢問(wèn)是5個(gè)0 所以肯定要找一種可以掃描一次得出結(jié)果不會(huì)重復(fù)計(jì)算的算法,這里介紹一種巧妙的方法: 離線操作,所謂離線就是將所有的詢問(wèn)都讀如后,根據(jù)需要進(jìn)行排序,這里一定要記錄一個(gè)id來(lái)保存輸入的順序,然后一個(gè)ans數(shù)組按照輸入順序儲(chǔ)存答案,然后從左到右的掃描一邊將所有的以當(dāng)前掃描的點(diǎn)為終止點(diǎn)的答案都保存起來(lái),最后按順序輸出ans 數(shù)組即可 對(duì)于這個(gè)題:一般按照右端點(diǎn)排序,因?yàn)橛叶它c(diǎn)代表這一個(gè)查詢的結(jié)束,所以按右端點(diǎn)排序有特殊的意義,因?yàn)槊看我コ貜?fù)的數(shù)字,可以考慮設(shè)一個(gè)last數(shù)組,標(biāo)記其在之前是否出現(xiàn)過(guò),如果出現(xiàn)過(guò)的化,將之前出現(xiàn)的地方的這個(gè)值更改成0 然后last數(shù)組的當(dāng)前值更新成當(dāng)前的位置,這樣樹(shù)狀數(shù)組中存放的值就肯定沒(méi)有重復(fù)元素了。 這種離線的思想很重要,一定要利用好將所有的數(shù)據(jù)排序后每次可以將相同的結(jié)尾的值一起算出來(lái)的性質(zhì),指針只用掃描一邊,每向后掃描后都將以這個(gè)值結(jié)尾的所有結(jié)果都處理出來(lái)。離線最大的好處是在依次向后更新last數(shù)組的時(shí)候前面的與其相關(guān)的詢問(wèn)已經(jīng)處理過(guò)了,所以去除前面的值,保留后面的不會(huì)影響前面的結(jié)果,也不會(huì)影響后面的計(jì)算。如果不離線,last 數(shù)組如果這樣更新的話,會(huì)影響到再次涉及前面的區(qū)間的和 代碼: 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 #define N 1000005 6 #define M 50005 7 #define numq 200005 8 #define ll long long 9 int Last[N]; 10 ll shusz[M]; 11 int gaga[M]; 12 ll ans[numq]; 13 struct Q { 14 int l ; 15 int r; 16 int id; 17 bool operator < (const Q a) const 18 { 19 return r<a.r; 20 } 21 }qq[numq]; 22 int lb(int i) 23 { 24 return i&(-i); 25 } 26 void add(int j , int t) 27 { 28 for(int i =j ;i < M ;i+=lb(i)) 29 { 30 shusz[i]+=t; 31 } 32 } 33 ll sum (int x) 34 { 35 ll ans = 0 ; 36 for(int i = x ; i > 0 ; i-=lb(i)) 37 { 38 ans+=shusz[i]; 39 } 40 return ans; 41 } 42 ll sum(int x , int y) 43 { 44 ll ans = sum(y)-sum(x-1);//注意是x-1 45 return ans; 46 } 47 int main() 48 { 49 int T ; 50 scanf("%d",&T); 51 for(int i =0 ;i < T ; i++) 52 { 53 int n; 54 scanf("%d",&n); 55 int tm; 56 for(int j = 1 ; j <= n ; j++) 57 { 58 scanf("%d",&tm); 59 gaga[j] = tm; 60 } 61 int m ; 62 scanf("%d",&m); 63 for(int j = 1 ;j <= m ;j++) 64 { 65 int l , r ; 66 scanf("%d%d",&l,&r); 67 qq[j].l = l ; 68 qq[j].r = r; 69 qq[j].id = j; 70 } 71 memset(Last,-1,sizeof(Last)); 72 memset(ans,0,sizeof(ans)); 73 memset(shusz,0,sizeof(shusz)); 74 sort(qq+1,qq+m+1); 75 int cur = 1;//記錄掃描到第幾個(gè)詢問(wèn) 76 for(int j = 1 ; j <= n ; j++)//掃描n個(gè)點(diǎn) 77 { 78 if(Last[gaga[j]] != -1) 79 add(Last[gaga[j]], -gaga[j]); 80 Last[gaga[j]] = j; 81 add(j, gaga[j]); 82 while(j == qq[cur].r) 83 { 84 ans[qq[cur].id] = sum(qq[cur].l, qq[cur].r); 85 cur++; 86 } 87 } 88 for(int j = 1; j <= m; j++) 89 printf("%lld\n", ans[j]); 90 } 91 return 0 ; 92 }?
轉(zhuǎn)載于:https://www.cnblogs.com/shanyr/p/4725462.html
總結(jié)
以上是生活随笔為你收集整理的Necklace(树状数组+离线操作)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: LeetCode 从零单刷个人笔记整理(
- 下一篇: 做个男人,做个成熟的男人,做个有城府的男