题目描述:T组数据,对于每组数据,n个数ai,Q个询问(L,R,h),询问L到R区间内≤h的数的个数
数据范围:30% n,Q≤10^3
100% T≤10 n,Q≤10^5 1≤L≤R≤n 0≤ai,h≤10^9
暴力枚举肯定是能过30%的点
对于100%的点,有一种离线做法是按照a,h把数组和询问分别排序,再用树状数组,比较容易想到,看代码能懂
const maxn=100005;
var id,id1,a,h,left,right,c,ans:array[0..maxn]of longint;
test,t,i,j,n,Q,k:longint;
procedure swap(var x,y:longint);
var t:longint;
begin
t:=x;x:=y;y:=t;
end;
procedure qsort(L,R:longint);
var i,j,mid:longint;
begin
i:=L;j:=R;mid:=a[random(R-L+1)+L];
repeat
while a[i]<mid do inc(i);
while a[j]>mid do dec(j);
if i<=j then begin
swap(a[i],a[j]);swap(id[i],id[j]);
inc(i);dec(j);
end;
until i>j;
if i<R then qsort(i,R);
if L<j then qsort(L,j);
end;
procedure qsort1(L,R:longint);
var i,j,mid:longint;
begin
i:=L;j:=R;mid:=h[random(R-L+1)+L];
repeat
while h[i]<mid do inc(i);
while h[j]>mid do dec(j);
if i<=j then begin
swap(h[i],h[j]);swap(left[i],left[j]);swap(right[i],right[j]);swap(id1[i],id1[j]);
inc(i);dec(j);
end;
until i>j;
if i<R then qsort1(i,R);
if L<j then qsort1(L,j);
end;
function lowbit(x:longint):longint;
begin
lowbit:=x and (-x);
end;
procedure add(x,y:longint);
begin
while x<=n do
begin
inc(c[x],y);
inc(x,lowbit(x));
end;
end;
function get(x:longint):longint;
var s:longint;
begin
s:=0;
while x>=1 do
begin
inc(s,c[x]);
dec(x,lowbit(x));
end;
exit(s);
end;
begin
assign(input,'query.in');reset(input);
assign(output,'query.out');rewrite(output);
readln(test);
for t:=1 to test do
begin
fillchar(c,sizeof(c),0);
readln(n,Q);
for i:=1 to n do
begin
id[i]:=i;
read(a[i]);
end;
readln;
for i:=1 to Q do
begin
id1[i]:=i;
readln(left[i],right[i],h[i]);
end;
qsort(1,n);
qsort1(1,Q);
i:=1;j:=1;
while j<=Q do
begin
if (i>n)or(h[j]<a[i]) then begin
ans[id1[j]]:=get(right[j])-get(left[j]-1);
inc(j);
end
else begin
add(id[i],1);
inc(i);
end;
end;
for i:=1 to Q do writeln(ans[i]);
end;
close(input);close(output);
end.
根据度老师给出的题解,还有在线做法:暴力主席树/树套树/kd-tree,此处不贴代码#因为没去写过,对于离线做法,还可以对位置排序,不过必须离线,大致意思差不多,但是会麻烦一点。
【写的有漏洞的,欢迎路过大神吐槽】
2016/11/13 17:05:33Ending.