"Sdut OJ 2610" Boring counting (Chairman tree)
Boring counting Time limit:3000ms Memory limit:65536k have questions? Dot here ^_^ Title DescriptionIn this problem given a number sequence P consisting of N integer and Pi was the ith element in the Sequenc E. Now you task is to answer a list of queries, for each query, please tell us among [L, R], how many Pi isn't less than A and not greater than B (l<= i <= R). In other words, your task is to count the number of pi (L <= i <= R, A <= Pi <= B).InputThe first line there are an integer T (1 < T <=), indicates the number of test cases.
For each case, the first line contains numbers n and m (1 <= N, M <= 50000), the size of sequence P, the number of queries. The second line contains N numbers pi (1 <= pi <= 10^9), the number sequence P. Then there is M lines, each line contains four number L, R, A, B (1 <= L, R <= N, 1 <= A, B <= 10^9) OutputFor each case, an at first output of line ' case #c: ', C is the case number start from 1. Then for each query, output a line contains the answer.Sample input
113 56 9 5 2 3 6 8 7 3 2 5 1 41 13 1 101 13 3 63 6 3 62 8 2 81 9 1 9
Sample output
Case #1:137369
Hint Source 2013 The first ACM University student Program design contest in Shandong Province sample program
Chairman of the tree-from just into the ACM in a few months often see the big ACM Group of the Word from time to time to take a bubble, but also in recent years a newly discovered data structure.
From then on this thing has been a very worship of posture (90° looking at
Yesterday, listen to Hongfeng giant, immediately clairvoyant enlightened ...
First, what is the chairman tree used for--solving the static interval K-Large
Chairman Tree Realization principle--with space for time, for n number, from left to right in order to record, so that n tree line tree form the Chairman tree.
The meaning of the interval in the line segment tree--the interval of numbering of all n numbers is discretized, from small to large.
The meaning of the segment tree-the number of numbers that have occurred in all the intervals until the current number is added.
Once the line tree is done, you will find that the complexity of building a tree every time is very high.
At the same time, you will find that when adding the number of I, it is necessary to create a new line segment tree, while the line segment tree is two fork structure, the first segment tree can actually be introduced by the I-1 Tree segment tree, so that in fact, the change of the node only log2 (n).
That is, a chain from the root to the leaf. In this way, for a repeating (unchanged) node, point directly to the node at the corresponding location of the i-1 tree.
In this way, when solving the number of numbers greater than x from left to right, I traverse the first segment tree, and find all the bands with the right boundary less than or equal to X, and count the cumulative sum
When searching for a number greater than x in the [l,r] interval, traverse the first R segment tree and use the answer minus the answer that traverses the first L segment tree.
When the number of k large in the [L,r] interval is obtained, by means of the complement, the right interval is continuously replenished with K, and when the larger number appears enough K, the answer is obtained.
For this problem, the number of the [a, b] range within the [l,r] interval is calculated. Traversal until interval [l,r] satisfies p[l] >= A, p[r] <= B (P is an array of discretized numbers)
The code is as follows:
#include <iostream> #include <cmath> #include <vector> #include <cstdlib> #include <cstdio > #include <cstring> #include <queue> #include <stack> #include <list> #include <algorithm > #include <map> #include <set> #define LL long long#define Pr pair<int,int> #define FREAD () freopen (" Data1.in "," R ", stdin) #define FWRITE () freopen (" Out.out "," w ", stdout) using namespace std;const int INF = 0x3f3f3f3f;const int msz = 10000;const int mod = 1e9+7;const double eps = 1e-8;struct node{//number of occurrences in the current interval int v;//left node right node number int l,r;}; Node nd[2333333];//primitive discretization int num[55555],qt[55555];//n tree segment tree root node int tm[55555];int tp,n,tot;//Establish new node return subscript int NewNode (int X) {nd[tp].v = X;ND[TP].L = ND[TP].R = -1;return tp++;} Initializes the first segment tree (all intervals are 0) int init (int l,int r) {if (L = = r) return NewNode (0), int mid = (L+R) >>1;int RT = NewNode (0); Nd[rt] . L = init (l,mid); ND[RT].R = init (mid+1,r); return RT;} Create a line segment tree int build (int root,int l,int r,int x) {//The new occurrence of a number--xint R in the current intervalt = NewNode (nd[root].v+1);//When the leaf node jumps out if (L = = r) Return rt;int mid = (l+r) >>1;if (x <= Qt[mid]) {ND[RT].R = ND[ROOT].R ; nd[rt].l = Build (nd[root].l,l,mid,x);} ELSE{ND[RT].L = ND[ROOT].L;ND[RT].R = Build (nd[root].r,mid+1,r,x);} return RT;} Query the number of [Low,high] within a [l,r] range of int Search (int root,int l,int r,int low,int High) {//Pay attention to the special sentence or you will not stop ... if (Qt[l] > High | | qt[ R] < low) return 0;if (Qt[l] >= low && qt[r] <= high) return nd[root].v;int mid = (l+r) >>1;if (qt[mid ] Return Search (Nd[root].l,l,mid,low,high), else if (qt[mid+1] <= low) return search (Nd[root].r,mid+1,r, >=) Low,high), Else return Search (Nd[root].l,l,mid,low,high) +search (Nd[root].r,mid+1,r,low,high);} int main () {//fread ();//fwrite (); int t,q;int st,en,low,high;scanf ("%d", &t), for (int z = 1; z <= t; ++z) {tp = 0;SCANF ( "%d%d", &n,&q); for (int i = 1; I <= n; ++i) {scanf ("%d", &num[i]); Qt[i] = Num[i];} Sort (qt+1,qt+n+1), tot = unique (qt+1,qt+n+1)-qt-1;tm[0] = init (1,tot); for (int i = 1; I <= n; ++i) Tm[i] = Build (Tm[i-1],1,tot,num[i]);p rintf ("Case #%d:\n", Z) and while (q--) {scanf ("%d%d%d%d",&st,&en,& Low,&high);p rintf ("%d\n", Search (Tm[en],1,tot,low,high)-search (Tm[st-1],1,tot,low,high));}} return 0;}
"Sdut OJ 2610" Boring counting (Chairman tree)