Feed the Dogs
Time Limit: 6000MS |
|
Memory Limit: 65536K |
Total Submissions: 17679 |
|
Accepted: 5561 |
Description
Wind loves pretty dogs very much, and she had n pet dogs. So Jiajia have to feed the dogs every day for wind. Jiajia loves wind, and not the dogs, so Jiajia use a special the-to feed the dogs. At lunchtime, the dogs would stand on one line, numbered from 1 to N, the leftmost one is 1, the second one is 2, and so on . In each feeding, Jiajia choose a inteval[i,j], select the k-th pretty dog to feed. Of course Jiajia have his own a-deciding, the pretty value of each dog. It should is noted that Jiajia does not want to feeds any position too much, because it may cause some death of dogs. If So, wind would be angry and the aftereffect would be serious. Hence Any feeding inteval won't contain another completely, though the intervals may intersect with each of the other.
Your task is to help Jiajia calculate which dog ate the food after each feeding.
Input
The first line contains N and m, indicates the number of dogs and the number of feedings.
The second line contains n integers, and describe the pretty value of each of the dog from left to right. You should notice, the dog with lower pretty, value is prettier.
Each of following m lines contain three integer i,j,k, it means that Jiajia feed the k-th pretty dog in this feeding.
You can assume that n<100001 and m<50001.
Output
Output file has m lines. The i-th line should contain the pretty value of the dog, who got the food in the i-th feeding.
Sample Input
7 21 5 2 6 3 7 41 5 32 7 1
Sample Output
32
Source
POJ Monthly--2006.02.26,zgl & TWB
the number of k small in the interval is obtained. and partition Tree classic POJ 2104 is a problem, the direct copy of the code to turn on AC.
/** Copyright (c) 2016, College of Computer and Control engineering, Yantai University * All rights reserved.* file name: k.cpp* Author: Tan Xinxin * Completion Date: April 15, 2016 * version number: v1.0*/#includ E <iostream> #include <stdio.h> #include <algorithm>const int maxn = 100005;using namespace Std;int sor[ maxn];//array struct node{int num[maxn];//the number int CNT[MAXN] of the current layer with the help of sort; Cnt[] Array is the core part of the tree//The number of left sub-trees in the left side of each element is saved} Tree[40];//40 is the number of layers of the tree//build code as follows void Buildtree (int l, int r, int d)//d is depth { if (L = = r)//recursive exit {return; } int mid = (l+r) >>1;//divides the left and right interval int opleft = l, Opright = mid+1;//to initialize the operation position of the left and the subtree int same_as_mid = 0;//and Sor[m ID] The number of the same number//calculate how many and Sor[mid] the same number (including mid) on the left side of the mid will be placed to the left subtree for (int i = mid; i > 0; i--) {if (sor[i] = = Sor [mid]) same_as_mid++; else break; } int cnt_left = 0;//is divided into the number of left subtrees for (int i = l; I <= R; i++) {//from L to R to start traversing if (Tree[d].num[i] < ; SOR[MID])//left {tree[d+1].num[opleft++] = Tree[d].num[i]; cnt_left++; Tree[d].cnt[i] = Cnt_left; } else if (tree[d].num[i] = = Sor[mid] && same_as_mid) {//the same is placed on the left subtree TREE[D+1].N um[opleft++] = Tree[d].num[i]; cnt_left++; Tree[d].cnt[i] = Cnt_left; same_as_mid--; } else//Right {tree[d].cnt[i] = Cnt_left; tree[d+1].num[opright++] = Tree[d].num[i]; }}//Recursive achievements Buildtree (L, Mid, d+1); Buildtree (mid+1, R, d+1);} int query (int l, int r, int d, int ql, int qr, int k)//1 N 0 A B k//in the node d [L,r] to find the K-small value {if (L = = r) in [B] and/or recursive exit return tree[d].num[l]; int mid = (l+r) >>1; int sum_in_left;//The number of elements in the left sub-tree of the next layer int LEFT;//[L,QL-1] The left side of the element is located in the next layer of the left subtree number if (QL = l) {//If QL is the left edge of the node there is CNT[QR] number into the left Sub-Tree Sum_in_left = TREE[D].CNT[QR]; left = 0; } else {//If QL is not the left edge of the node then there is cnt[qr]-cnt[ql-1] number entered the left subtree Sum_in_left = TREE[D].CNT[QR]-TREE[D].CNT[QL-1]; left = tree[D].CNT[QL-1]; } if (Sum_in_left >= k) {//To find the point in the Zuozi//determine the location of the next inquiry://If there is left on the left side of the QL to enter the Ieft subtree//Then QL to the first in the QR to enter the left sub-tree must Fixed in l+left position int new_ql = L+left; int NEW_QR = new_ql+sum_in_left-1; Return query (L, Mid, d+1, NEW_QL, NEW_QR, K); } else//to find the point in the right subtree {//OK next ask for the position int a = ql-l-left;//means the left half of the current interval is [L,QL-1] in the next layer is the number of the right child int b = QR-QL + 1-sum_in_left;//means that the right half of the current interval is [QL,QR] in the next layer is the number of right children int NEW_QL = mid + A + 1; int NEW_QR = mid + A + B; K-sum_in_left means to subtract the number of left subtrees that have entered in the interval return query (mid+1, R, D+1, NEW_QL, NEW_QR, k-sum_in_left); }}int Main () {int n,m,i,a,b,k; scanf ("%d%d", &n,&m); for (I=1; i<=n; ++i) {scanf ("%d", &sor[i]);//INSERT into the SOR array tree[0].num[i]=sor[i];//and insert the first layer} sort ( SOR+1,SOR+N+1);//Ascending Buildtree (1,n,0);//achievements for (I=1; i<=m; ++i) {//Query scanf ("%d%d%d", &a,&b,& ; k); printf ("%d\n", Query (1,n,0,a,b,k)); } return 0;}
POJ 2761-feed The Dogs (dividing tree) to find the number of K small within the interval