Miyu original, post Please note: Reprinted from __________ White House
Question address:
Http://acm.hdu.edu.cn/showproblem.php? PID = 1, 3450
Description:
Counting Sequences
Time Limit: 2000/1000 MS (Java/others) memory limit: 32768/65536 K (Java/Others)
Total submission (s): 312 accepted submission (s): 105
Problem descriptionfor a set of sequences of integers {A1, A2, A3 ,... an}, we define a sequence {aI1, ai2, ai3... AIK} in which 1 <= I1 <I2 <I3 <... <ik <= N, as the sub-sequence of {A1, A2, A3 ,... an }. it is quite obvious that a sequence with the length N has 2 ^ n sub-sequences. and for a sub-sequence {aI1, ai2, ai3... AIK}, if it matches the following qualities: k> = 2, and the neighboring 2 elements have the difference not larger than D, it will be defined as a perfect sub-sequence. now given an integer sequence, calculate the number of its perfect sub-sequence.
Inputmultiple test cases the first line will contain 2 integers n, D (2 <= n <= 100000,1 <= d = <= 10000000) the second line N integers, representing the suquence
Outputthe Number of perfect sub-sequences mod 9901
Sample Input
4 21 3 7 5
Sample output
4
Question Analysis:
(Line Segment tree | tree array) + dp
You can use a line segment tree or a tree array. Unfortunately, I still don't have a line segment tree. The following is an analysis of tree array problems:
Because the question requires K> = 2, andThe absolute value of the difference between adjacent elements is not greater than D.It has been a long struggle and I have never understood"And
Neighboring 2 elements have the difference not larger than D ", the English level is too bad.
The explanation of AMB is as follows: 0rz ...........
To simplify the problem, we discuss K> = 1:
Because the input data has a large range,2 <= n <= 100000,1 <= d = <= 10000000, so sort the data first and then useHash [Max]Perform discretization.
Of course, the original array needs to be saved in another array. After processing is complete, we can understand it as follows: Use a tree ArrayCOM [POS], (POS is the bit of num in the hash Array
Set ). number of records that can form a perfect string with num. the perfect substring in the initial state is 0, and each time a number is added, the number num is equal to the first one that is smaller than him and cannot exceed D.
The number is the perfect string with the first number that is larger than and less than D. The tree array is updated and all substrings and sum are obtained.AlgorithmIt is done with K> = 1, and
The question must be K> = 2. That is to say, N numbers are calculated n times more, so (Sum-N) % 9901 is the question. (Don't forget mod .......)
CodeAs follows:
/* Miyu original, post Please note: Reprinted from __________ White House http://www.cnblog.com/MiYuAuthor by: miyutest: 1 program: 3450 */# include <iostream> # include <algorithm> using namespace STD; const int max = 100010; const int mod = 9901; int ncount = 0; int COM [Max]; int hash [Max]; int num1 [Max]; int num2 [Max]; int N, D; inline int low (int x) {return X & (-x);} void modify (int x, int Val) {// modify while (x <= ncount) {COM [x] + = Val; x + = low (x) ;}} int QUY (int x) {// query int sum = 0; while (x> 0) {sum + = com [X]; X-= low (x);} return sum;} int find1 (INT Val) {// the first count of the Binary Search <= Val int beg = 1, end = ncount; int mid = (beg + end)> 1; int res = mid; while (beg <= END) {If (hash [Mid] <= Val) {beg = Mid + 1; Res = mid;} else {end = mid-1 ;} mid = (beg + end)> 1;} return res;} int find2 (INT va L) {// the first count of the Binary Search <= Val int beg = 1, end = ncount; int mid = (beg + end)> 1; int res = mid; while (beg <= END) {If (hash [Mid] <Val) {beg = Mid + 1;} else {end = mid-1; Res = mid ;} mid = (beg + end)> 1;} return res;} inline bool scan_d (Int & num) // enter {char in; bool isn = false; in = getchar (); If (in = EOF) return false; while (in! = '-' & (In <'0' | in> '9') in = getchar (); If (in = '-') {isn = true; num = 0;} else num = In-'0'; while (in = getchar (), in> = '0' & in <= '9') {num * = 10, num + = In-'0';} If (ISN) num =-num; return true;} int main () {While (scan_d (n) & scan_d (D) {for (INT I = 0; I <n; ++ I) {scan_d (num1 [I]); num2 [I] = num1 [I];} Sort (num1, num1 + n); hash [1] = num1 [0]; ncount = 1; for (INT I = 1; I <n; ++ I) {// data discretization If (num1 [I]! = Num1 [I-1]) hash [++ ncount] = num1 [I];} memset (COM, 0, sizeof (COM); For (INT I = 0; I <n; ++ I) {int Pos = find1 (num2 [I]); // find the hash subscript of the current element int pre = find1 (num2 [I] + D ); // find the first number of <= num2 [I] + D int tail = find2 (num2 [I]-D ); // find> = the first number of num2 [I]-D int val = QUY (pre)-QUY (tail-1) + 1; // The number of elements in the interval [num2 [I]-D, num2 [I] + D] + a new element modify (Pos, Val % mod );} cout <(QUY (ncount)-N) % mod <Endl; // calculated based on [ELEM-D, ELEM + D] of an element, question requirements K> = 2, minus n} return 0 ;}