【区间最值】、sequence
Sequence
给出一个长度为N的序列A1,A2, · · · ,AN,其中每项都是小于10^5的自然数。
现在有M个询问,每个询问都是Ai · · ·Aj中第k小的数等于多少。
输入格式
第一行两个正整数N,M。
第二行N个数,表示序列A1,A2, · · · ,AN。
紧着的M行,每行三个正整数i, j, k(k ≤ j − i + 1),表示询问Ai...Aj中第k小的数等于多少。
输出格式
共输出M行,第i行输出第i个询问的答案。
输入样例
4 3
4 1 2 3
1 3 1
2 4 3
1 4 4
输出样例
1
3
4
数据范围
在60%的数据中,1 ≤ N ≤ 1000,1 ≤ M ≤ 1000
在100%的数据中,1 ≤ N ≤ 10000,1 ≤ M ≤ 2000
【source】
1.朴素:每次就把这个区间快排,直接输出第k小的数。这样只有60、
朴素code
procedure work;
var i,j,k,x,y:longint;
begin
for i:=1 to m do
begin
b:=a;//b为临时数组,因为在这次操作中会改变原数组的顺序
readln(x,y,k);
qsort(x,y);
writeln(a[x+k-1]);
a:=b;
end;
end;
2.AC:由于每次询问只与下标有关,那么把数据按权值升排后,下标就无序了。
每次读入一个区间,在有序序列中从左往右扫描,当遇到下标在区间内时,+1、直到这个值等于所求的k就退出、
AC-Code【Java版本】
import java.util.*;
class Number{
int data; //数值
int num; //实际下标
}
class Untitled {
static class mycmp implements Comparator<Number>{
public int compare(Number n1, Number n2){
return n1.data-n2.data;
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n,m;
int left,right,find;
n = sc.nextInt();
m = sc.nextInt();
Number[] a = new Number[10000];
for(int i=0;i<n;i++){
a[i] = new Number();
a[i].data = sc.nextInt();
a[i].num = i;
}
//将data排序
Arrays.sort(a, 0, n, new mycmp());
for(int i=0;i<n;i++){
left = sc.nextInt();
right = sc.nextInt();
find = sc.nextInt();
int sum = 0;
for (int j=0;j<n;j++){
if(a[j].num >=left-1 && a[j].num<=right-1){
sum+=1;
if (sum == find ){
System.out.println(a[j].data);
break;
}
}
}
}
}
}
AC-code【Pascal版本】
program sequence;
type node=record
data,num:longint;
end;
var a:array[0..10000]of node;
n,m,left,right,find:longint;
procedure init;
begin
assign(input,'sequence.in');reset(input);
assign(output,'sequence.out');rewrite(output);
end;
procedure endit;
begin
close(input);close(output);
halt;
end;
procedure qsort(s,t:longint);
var i,j:longint;
x,tem:node;
begin
i:=s;j:=t; x:=a[(i+j)div 2];
repeat
while a[i].data<x.data do inc(i);
while a[j].data>x.data do dec(j);
if i<=j then
begin
tem:=a[i];a[i]:=a[j];a[j]:=tem;
inc(i);dec(j);
end;
until i>j;
if s<j then qsort(s,j);
if i<t then qsort(i,t);
end;
procedure main;
var i,j,sum:longint;
begin
readln(n,m);
for i:=1 to n do
begin
read(a[i].data);
a[i].num:=i;
end;
qsort(1,n);
for i:=1 to m do
begin
readln(left,right,find);
sum:=0;
for j:=1 to n do
if (a[j].num>=left)and(a[j].num<=right) then
begin
inc(sum);
if sum=find then
begin
writeln(a[j].data);
break;
end;
end;
end;
end;
begin
init;
main;
endit;
end.