Hdu3874necklace (line segment tree or bit + offline processing)

Source: Internet
Author: User

-> Question, click here <-

Calculate the sum of numbers in different intervals for N numbers.

Question Analysis: N numbers are given, not changed, and ranges are also given. Since the sum of numbers in any range is not repeated, It is very similar to this Super Mario. We can process all the queries offline. We need to sort the query intervals by the right breakpoint because of the sum of non-repeated numbers. In this way, we can scan the sequence from left to right. If no number exists before, We can insert it directly. If so, delete the last position where the number appeared and insert it again at the current position. If the scan position is greater than the right endpoint of the range to be queried, process the query. Since all the query intervals have been sorted by the right endpoint, we ensure that all repeated numbers are also inserted in the back-to-right corner, and each repeated number is inserted only once, therefore, we can ensure that the numbers in the expected range are not repeated. Since the given number cannot exceed 1000000, you can directly open a large array. If the number is larger, it will be hashed. My line segment tree has been running for more than 3000 Ms. Because this question only requires a range and so bit is a better choice. After reading the ranklist, it seems that it is all in 1000 ms +, this indicates that the background summer vacation is awesome. Haha.

Line Segment Tree Code:

# Include <iostream> # include <cstdio> # include <cstring> using namespace STD; const int n = 1000005; const int nn = 50005; typedef _ int64 ll; int hash [N]; int n, m; int LCM [NN]; ll tree [NN <2]; struct node {int L, R, ID ;} ask [NN <2]; ll ans [NN <2]; int CMP (struct node A, struct Node B) {if (. r! = B. r) return. r <B. r; else return. L <B. l;} void build (INT num, int S, int e) {tree [num] = 0; If (S = e) return; int mid = (S + E)> 1; build (Num <1, S, mid); Build (Num <1 | 1, Mid + 1, e);} void insert (INT num, int S, int e, int POs, int add) {If (S = e) {tree [num] + = add; return;} int mid = (S + E)> 1; if (Pos <= mid) insert (Num <1, S, mid, POs, add ); else insert (Num <1 | 1, Mid + 1, E, POs, add ); tree [num] = tree [num <1] + tree [num <1 | 1];} ll query (INT num, int S, int e, int l, int R) {If (S = L & R = e) return tree [num]; int mid = (S + E)> 1; if (r <= mid) return query (Num <1, S, mid, L, R); else {If (L> mid) return query (Num <1 | 1, Mid + 1, E, L, R); else return query (Num <1, S, mid, L, mid) + query (Num <1 | 1, Mid + 1, E, Mid + 1, R) ;}} int main () {int I, T; scanf ("% d", & T); While (t --) {scanf ("% d", & N); memset (hash,-1, sizeof (hash); for (I = 1; I <= N; I ++) scanf ("% d", & LCM [I]); scanf ("% d", & M); for (I = 0; I <m; I ++) {scanf ("% d ", & ask [I]. l, & ask [I]. r); ask [I]. id = I + 1;} Sort (Ask, ask + M, CMP); Build (1, 1, n); Int J = 1; for (I = 0; I <m;) {If (j <= ask [I]. r) {If (hash [LCM [J] =-1) {insert (, N, J, LCM [J]); hash [LCM [J] = J; // record location} else // you have inserted LCM [J] {insert (, n, hash [LCM [J],-LCM [J]); // Delete hash [LCM [J] = J; // update position insert (, N, J, LCM [J]);} J ++;} else {ans [ask [I]. id] = query (1, 1, n, ask [I]. l, ask [I]. r); I ++ ;}}for (I = 1; I <= m; I ++) printf ("% i64d \ n", ANS [I]);} return 0;} // 3328ms9380k

Bit code:

# Include <iostream> # include <cstdio> # include <cstring> using namespace STD; const int n = 1000005; const int nn = 50005; typedef _ int64 ll; int hash [N]; int n, m; int LCM [NN]; ll tree [NN <2]; struct node {int L, R, ID ;} ask [NN <2]; ll ans [NN <2]; int CMP (struct node A, struct Node B) {if (. r! = B. r) return. r <B. r; else return. L <B. l;} void build (INT num, int S, int e) {memset (tree, 0, sizeof (tree);} void insert (INT num, int s, int e, int POs, int add) {int x = Pos; while (x <= e) {tree [x] + = add; X + = x & (-x) ;}} ll sum (INT p) {ll SSUM = 0; while (p) {SSUM + = tree [p]; p-= P & (-P);} return SSUM;} ll query (INT num, int S, int e, int L, int R) {return sum (r) -sum (L-1);} int main () {int I, T; scanf ("% d", & T); While (t --) {scanf ("% d", & N); memset (hash,-1, sizeof (hash); for (I = 1; I <= N; I ++) scanf ("% d", & LCM [I]); scanf ("% d", & M); for (I = 0; I <m; I ++) {scanf ("% d", & ask [I]. l, & ask [I]. r); ask [I]. id = I + 1;} Sort (Ask, ask + M, CMP); Build (1, 1, n); Int J = 1; for (I = 0; I <m;) {If (j <= ask [I]. r) {If (hash [LCM [J] =-1) {insert (, N, J, LCM [J]); hash [LCM [J] = J; // record location} else // you have inserted LCM [J] {insert (, n, hash [LCM [J],-LCM [J]); // Delete hash [LCM [J] = J; // update position insert (, N, J, LCM [J]);} J ++;} else {ans [ask [I]. id] = query (1, 1, n, ask [I]. l, ask [I]. r); I ++ ;}}for (I = 1; I <= m; I ++) printf ("% i64d \ n", ANS [I]);} return 0;} // 2453ms9916k

It seems that it is not very fast... .. Okay, I'm frustrated...

But if so...

# Include <iostream> # include <cstdio> # include <cctype> # include <cstring> using namespace STD; const int n = 1000005; const int nn = 50005; typedef _ int64 ll; int hash [N]; int n, m; int LCM [NN]; ll tree [NN <2]; struct node {int L, R, ID;} ask [NN <2]; ll ans [NN <2]; int CMP (struct node A, struct Node B) {if (. r! = B. r) return. r <B. r; else return. L <B. l;} void build (INT num, int S, int e) {memset (tree, 0, sizeof (tree);} void insert (INT num, int s, int e, int POs, int add) {int x = Pos; while (x <= e) {tree [x] + = add; X + = x & (-x) ;}} ll sum (INT p) {ll SSUM = 0; while (p) {SSUM + = tree [p]; p-= P & (-P);} return SSUM;} ll query (INT num, int S, int e, int L, int R) {return sum (r) -sum (L-1);} int nextint () {char C; int ret; while (isspace (C = getchar (); ret = C-'0 '; while (C = getchar ()> = '0' & C <= '9') ret = RET * 10 + C-'0'; return ret ;} int main () {int I, T; // scanf ("% d", & T); t = nextint (); While (t --) {// scanf ("% d", & N); n = nextint (); memset (hash,-1, sizeof (hash); for (I = 1; I <= N; I ++) {// scanf ("% d", & LCM [I]); LCM [I] = nextint ();} M = nextint (); // scanf ("% d", & M); for (I = 0; I <m; I ++) {ask [I]. L = nextint (); ask [I]. R = nextint (); // scanf ("% d", & ask [I]. l, & ask [I]. r); ask [I]. id = I + 1;} Sort (Ask, ask + M, CMP); Build (1, 1, n); Int J = 1; for (I = 0; I <m;) {If (j <= ask [I]. r) {If (hash [LCM [J] =-1) {insert (, N, J, LCM [J]); hash [LCM [J] = J; // record location} else // you have inserted LCM [J] {insert (, n, hash [LCM [J],-LCM [J]); // Delete hash [LCM [J] = J; // update position insert (, N, J, LCM [J]);} J ++;} else {ans [ask [I]. id] = query (1, 1, n, ask [I]. l, ask [I]. r); I ++ ;}}for (I = 1; I <= m; I ++) printf ("% i64d \ n", ANS [I]);} return 0;} // 1640ms9912k

I wiped it, and the efficiency soared. Ah, ah, the amazing String Parsing acceleration...

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.