[Topic] Weight Line Segment Tree

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:
write picture description here
we just add 1 to the point with a weight of 1, indicating that it occurs once.
Add 5 again:
write picture description here
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:
write picture description herethis is all put in...
Suppose, we are looking for the third small when 7 is just put in, this is the situation:
write picture description here
first, we are at the root node, go down to find the third 3 big:
write picture description herefind that we have only two numbers on the left, then the third largest must be on the right, then we go to the right:
write picture description herethen, 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! !
write picture description hereThe 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.
write picture description here
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.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326046981&siteId=291194637