-> 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...