K-query
Given a sequence of n numbers a1, A2, ..., an and a number of k-queries. A k-query is a triple (I, J, K) (1≤i≤j≤n). For each k-query (I, J, K), you have to return the number of elements greater than k in the subsequence ai, ai+1, ..., AJ.
Input
- Line 1:n (1≤n≤30000).
- Line 2:N numbers a1, A2, ..., an (1≤ai≤109).
- Line 3:q (1≤q≤200000), the number of k-queries.
- The next q lines, each line contains 3 numbers I, J, K representing a k-query (1≤i≤j≤n, 1≤k≤109).
Output
- For each k-query (I, J, K), print the number of elements greater than k in the subsequence ai, ai+1, ..., AJ in a single L Ine.
Example
Input
5
5 1 2 3 4
3
2 4 1
4 4 4
1 5 2
Output
2
0
3
Intent: Given an array, q queries, each query how many numbers are greater than k in the interval [L, R].
This question is relatively old and watery, but I feel that I can handle a lot of questions that are asked a lot offline. The ideas are worth digging and learning.
For example, consider the line segment tree. The leaves of this line segment tree are all 1. All queries are sorted from small to large according to the size of k. Then for each query, the position of the number less than the current query k can be placed in the line segment tree. 0, then the result is the interval sum problem of the line segment tree. After Q queries, all numbers are added. The complexity is not high. O (N + Q * log N)
2 const int MAXN = 3e4+10;
3 const int MAXQ = 2e5+10;
4 struct Node{
5 int L, R, k, idx;
6 Node (int L = 0, int R = 0, int k = 0, int idx = 0):
7 L(L), R(R), k(k), idx(idx){}
8 bool operator < (const Node &rhs)const{
9 return k < rhs.k;
10 }
11 }Q[MAXQ];
12 int sum[MAXN << 2];
13 void build (int l, int r, int pos){
14 if (l == r){
15 sum[pos] = 1;
16 return;
17 }
18 int mid = (l + r) >> 1;
19 build(l, mid, pos<<1);
20 build(mid+1, r, pos<<1|1);
21 sum[pos] = sum[pos<<1] + sum[pos<<1|1];
22 }
23 void update (int l, int r, int pos, int x, int val){
24 if (l == r){
25 sum[pos] = val;
26 return;
27 }
28 int mid = (l + r) >> 1;
29 if (x <= mid){
30 update(l, mid, pos<<1, x, val);
31 }else{
32 update(mid+1, r, pos<<1|1, x, val);
33 }
34 sum[pos] = sum[pos<<1] + sum[pos<<1|1];
35 }
36 int query (int l, int r, int pos, int ua, int ub){
37 if (ua <= l && ub >= r){
38 return sum[pos];
39 }
40 int mid = (l + r) >> 1;
41 int res = 0;
42 if (ua <mid){
43 res += query(l, mid, pos<<1, ua, ub);
44 }
45 if (ub > mid){
46 res += query(mid+1, r, pos<<1|1, ua, ub);
47 }
48 return res;
49 }
50 int ans[MAXQ], IDX[MAXN], val[MAXN];
51 bool cmp(int i, int j){
52 return val[i] < val[j];
53 }
54 int main() {57 int n, q;
58 while (~ scanf ("%d", &n)){
59 for (int i = 0; i < n; i++){
60 scanf ("%d", val+i);
61 IDX[i] = i;
62 }
63 sort (IDX, IDX+n, cmp);
64 scanf ("%d", &q);
65 for (int i = 0; i < q; i++){
66 int ua, ub, k;
67 scanf ("%d%d%d", &ua, &ub, &k);
68 Q[i] = Node(ua, ub, k, i);
69 }
70 sort (Q, Q+q);
71 build(1, n, 1);
72 int p = 0;
73 for (int i = 0; i < q; i++){
74 while (p < n && val[IDX[p]] <= Q[i].k){
75 update(1, n, 1, IDX[p]+1, 0);
76 p++;
77 }
78 ans[Q[i].idx] = query(1, n, 1, Q[i].L, Q[i].R);
79 }
80 for (int i = 0; i < q; i++){
81 printf("%d\n", ans[i]);
82 }
83 }
84 return 0;
85 }
Then look at the 15 programming of the beauty of a problem.
You are playing a game of guessing numbers with Xiaoice. The Xiaoice first generates a sequence of integers A1, A2, ..., an n. In each round of the game, the Xiaoice will give an interval range [L, R], and then you have to guess a number k. If K is in AL, al+1, ..., AR, then you win.
After a few rounds of experimenting, you find the game too difficult (boring). Xiaoice decide to give you some hints, every time you guess, Xiaoice will tell you K with AL, al+1, ..., the absolute difference of the nearest number in Ar, i.e. min (| ai-k|), L≤i≤r.
This problem can be persisted in the line tree, but the code is large, in addition to offline + line tree, the nearest K value is either smaller than K or larger than K. When you think about being smaller than K, first put all the numbers and queries together sorting, sorted by value, the query and the number separated, and then from small to large to join the line tree, then for a query [L, R] at this time the Segment Tree section [L, R] Maximum is the nearest k smaller than the K value, the same can be found the closest to the K The value of K. Then you can compare them. Code slightly.
Spoj--k-query (line segment tree offline) working offline to solve the problem