Introduction
Everyone knows the line segment tree, if you don't know it, click here . Our line segment tree is a line segment tree with the label as the key. As the name suggests, the weighted line segment tree is a line segment tree with the weight as the key. In fact, when implementing, it is simpler than the line segment tree. If you really understand the line segment tree, the weight line segment tree is generally used to quickly find the kth largest (or smallest) of an interval. If you can splay, please automatically point ×.
working principle
The weight segment tree is used to find the kth largest (or smallest). Suppose we have a string of numbers: 1,5,2,7,4,6. You are required to insert a number in order each time, and find the current 3rd smallest. We can use the weight line segment tree for this problem. Suppose, let's add 1 first:
we just add 1 to the point with a weight of 1, indicating that it occurs once.
Add 5 again:
add one to the place where the weight is 5, indicating that it also appears once.
Then look at the situation where all are added:
this is all put in...
Suppose, we are looking for the third small when 7 is just put in, this is the situation:
first, we are at the root node, go down to find the third 3 big:
find that we have only two numbers on the left, then the third largest must be on the right, then we go to the right:
then, we have to subtract the 2 on the left, which means that we were originally the third smallest, and now find the smallest on the right Enough.
Then, we know that there is one current left son, so just meet the conditions, go in, and we will find it! !
The answer is 5!
Is it very tasteful, in fact, it is not difficult to achieve.
Let's have an example!
example
black box
Description
Black Box is a primitive database. It can store an array of integers and has a special variable i. Initially Black Box is empty and i is equal to 0. This Black Box has to process a sequence of commands.
There are only two commands:
ADD(x): put the x element into the Black Box;
GET: add 1 to i, and output the i-th smallest number in the Black box.
Remember: the i-th smallest number is the i-th element of the numbers in the Black Box sorted in ascending order.
For example,
let 's demonstrate a command string with 11 commands.
Now the requirement is to find out the best way to handle a given command string. ADD and GET commands each have a maximum of 200,000.
Now use two integer arrays to represent the command string:
1. A(1), A(2), …, A(M): A string of elements that will be put into the Black Box. Each number is an integer whose absolute value does not exceed 2000000000, M <= 200000. For example, the above example is A=(3, 1, -4, 2, 8, -1000, 2).
2. u(1), u(2), …, u(N): means u(j) A GET command appears after the element is placed in the Black Box. For example, u=(1, 2, 6, 6) in the above example. Enter data without making mistakes.
Input
first line, two integers, M, N,
second line, M integers, representing A(1)...A(M),
third line, N integers, representing u(1)...u( N).
Output
Output Black Box The output string derived from the command string, one number per line.
Sample Input
7 4
3 1 -4 2 8 -1000 2
1 2 6 6
Sample Output
3
3
1
2
Data Constraint
[Data size]
For 30% of the data, M<=10000;
for 50% of the data, M<=100000 ;
for 100% of the data, M<=200000.
This question is actually a bare weighted line segment tree. I won't say more, just look at the standard distance for yourself!
var
a,b,al,bz,wz,wz1:array[0..200000]of longint;
f,fy:array[0..262129]of longint;
n,i,t,m,nn,j,k,len:longint;
procedure kp(l,r:longint);
var
i,j,mid:longint;
begin
i:=l;
j:=r;
mid:=a[l];
while i<=j do
begin
while a[i]<mid do inc(i);
while a[j]>mid do dec(j);
if i<=j then
begin
a[0]:=a[i];
a[i]:=a[j];
a[j]:=a[0];
wz[0]:=wz[i];
wz[i]:=wz[j];
wz[j]:=wz[0];
inc(i);
dec(j);
end;
end;
if l<j then kp(l,j);
if r>i then kp(i,r);
end;
procedure make(v,l,r,x:longint);
var
mid:longint;
begin
mid:=(l+r) div 2;
if l=r then
begin
inc(f[v]);
fy[v]:=a[bz[l]];
exit;
end
else
begin
if x<=mid then make(v*2,l,mid,x);
if x>mid then make(v*2+1,mid+1,r,x);
end;
f[v]:=f[v*2]+f[v*2+1];
end;
function find(v,l,r,k:longint):longint;
var
mid:longint;
begin
mid:=(l+r) div 2;
if l=r then exit(fy[v])
else
begin
if k<=f[v*2] then exit(find(v*2,l,mid,k));
if k>f[v*2] then exit(find(v*2+1,mid+1,r,k-f[v*2]));
end;
f[v]:=f[v*2]+f[v*2+1];
end;
begin
readln(n,m);
for i:=1 to n do
begin
read(a[i]);
wz[i]:=i;
end;
for i:=1 to m do
read(b[i]);
kp(1,n);
j:=0;
for i:=1 to n do
if a[i]<>a[i-1] then
begin
inc(j);
al[i]:=j;
bz[j]:=i;
wz1[wz[i]]:=i;
end
else
begin
al[i]:=al[i-1];
wz1[wz[i]]:=i;
end;
len:=j;
j:=1;
k:=0;
for i:=1 to n do
begin
make(1,1,len,al[wz1[i]]);
while b[j]=i do
begin
inc(k);
inc(j);
writeln(find(1,1,len,k));
end;
end;
end.