Using Treap to realize rank tree __treap realize rank tree

Source: Internet
Author: User
Tags rand cmath

From the "introduction of the first classical algorithm competition guide" 1.Treap to achieve the ranking tree 1. A simple introduction to Treap is a tree that has two weights of key values and precedence values. For the key value, this tree is a two-fork sort tree. For precedence, this tree is a heap, that is, in any subtree of this tree, the root has the highest precedence. It is not difficult to prove that if the precedence of each node is given in advance and is not equal, the shape of the entire tree is uniquely determined, regardless of the insertion order of the elements. In the treap insertion algorithm, the priority of each node is randomly determined. Therefore, the time complexity of each operation is also random. Fortunately, the expected time complexity for inserting, deleting, and finding is all O (Nlogn). definition of 2.Treap node

struct node
{
    node *ch[2];//the left and right subtree
    int r;//Precedence, the higher the number, the higher the precedence
    int v;//value
    int s;//node Total
    int cmp (int x) const{
        if (x==v) return-1;
        Return x<v?0:1;
    }
};
3. RotateDivided into left-handed and right-handed
D=0 represents the left rotation, d=1 represents the right rotary
void rotate (node* &o,int D)
{node*
    k=o->ch[d^1];
    o->ch[d^1]=k->ch[d];
    k->ch[d]=o;
    o=k;
}
Note tip: Because d=0 or 1,d^1 are priced at 1-d, they are faster to compute. About the left or right, you can own Baidu ... 4. Insert NodeWhen you insert a node, you randomly assign a priority to the new node, and then perform a normal insertion algorithm (in which subtree, depending on the size of the key value). After execution, use the left and right rotation to maintain the heap nature of the treap tree. If you want to use recursive implementations, you need to decide whether to rotate after a recursive insert.
Inserts a key value x in a subtree with the root of O, modifying o
void Insert (node* &o,int x)
{
    if (o==null) {
        o=new Node ();
        o->ch[0]=o->ch[1]=null;
        o->v=x;
        O->r=rand ();
    }
    else{
        int d=o->cmp (x);
        Insert (o->ch[d],x);
        if (o->ch[d]->r>o->r) {
            rotate (o,d^1);
        }
    }
}

5. Delete nodeDelete the node, if only one subtree, directly with this Shang tree instead of the node to be deleted to be the root can be (Note that O is the leaf of the case also conforms to). The trouble is that O has two Shang trees, we first rotate the higher priority to the root and then recursively delete the node o in another Shang tree. For example, a Zoozi node has a higher priority and must be right-handed, otherwise it will violate the heap properties.
void Remove (node* &o,int x)
{
    int d=o->cmp (x);
    if (d==-1) {
        if (o->ch[0]==null) o=o->ch[1];
        else if (o->ch[1]==null) o=o->ch[0];
        else{
            int d2= (o->ch[0]->r>o->ch[1]->r?1:0);
            Rotate (O,D2);
            Remove (o->ch[d2],x);
        }
    else{
        Remove (o->ch[d],x);
    }

6. Lookup functionThe code above does not handle the two cases where the "to insert value exists" and "no value to be deleted", so make a lookup once before calling the response function.
int find (node* o,int x)
{while
    (o!=null) {
        int d=o->cmp (x);
        if (d==-1) return 1;//exists
        else o=o->ch[d];
    }
    Return 0;//does not exist
}

7. Rank TreeIn the TREAP implementation ranking tree, each node has an additional field size that represents the total number of nodes of the subtree with which it is rooted. The rank tree can do the following two kinds of operations: Kth (k): Find the K small element rank (x): the rank of value x, that is, the number of nodes smaller than x plus 1. The way to implement a rank tree with Treap is to add a size field and then write a maintain function, as follows:
void maintain ()
{
    S=1;
    if (ch[0]!=null) s+=ch[0]->s;
    if (ch[1]!=null) s+=ch[1]->s;
}
The rotation operation is also modified to call the maintain function recalculation when s may change
D=0 represents the left rotation, d=1 represents the right rotary
void rotate (node* &o,int D)
{node*
    k=o->ch[d^1];
    o->ch[d^1]=k->ch[d];
    k->ch[d]=o;
    Note First maintain o, then maintain K
    o->maintain ();
    K->maintain ();
    o=k;
}
For a specific template, see the following example. 2.la5031 1. Original titlehttps://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&itemid=8&page=show_problem& problem=3032

There is an endless graph of n vertices m edges, each node having an integer weight value. The task is to perform a series of operations, operating in three different ways. 1.D x: Delete the edge of ID x to ensure that each edge is deleted at most one time 2.Q X k: Calculate the node x connected with the node (including the x itself), the K large weight value, if not present, return 0. 3.C x V: Change the weight of node X to V. The symbol for the end of the action sequence is E. 2. Solving IdeasThe only way to do this is to design an offline algorithm so that the order of operations can be reversed. Read all the operations first, perform all operations D, and insert the edges gradually into the diagram in reverse order. Maintain a point right in a connected component with a rank tree. C operation corresponds to modify operation, q operation corresponds to KTH operation, and perform d operation, if two endpoints in a connected component, obviously have no effect. Otherwise, it should look like the combined operation of the set, "weights" smaller and to the "weight" of the larger root node, where the weight is the number of knots, such a strategy is heuristic merging. With heuristic merging, it can be handled efficiently (think about and check the collection) for any node, whenever it is moved to a new tree, the node's tree size is doubled at least, and any node is "moved" at most logn times, and an O (LOGN) time is required for each move, so the total time complexity is O (nlog^2n). 3.AC Code
#include <algorithm> #include <cctype> #include <cmath> #include <cstdio> #include <cstdlib&
Gt
#include <cstring> #include <iomanip> #include <iostream> #include <map> #include <queue> #include <string> #include <set> #include <vector> #include <cmath> #include <bitset> #
Include<sstream> using namespace std;  #define INF 0x7fffffff struct Node {node *ch[2];//left and right subtree int r;//random priority int v;//value int s;//node total node (int
        V): V (v) {ch[0]=ch[1]=null;
        R=rand ();
    S=1;
        int cmp (int x) const{if (x==v) return-1;
    Return x<v?0:1;
        } void Maintain () {S=1;
        if (ch[0]!=null) s+=ch[0]->s;
    if (ch[1]!=null) s+=ch[1]->s;

}
};
    The d=0 represents the left, and the d=1 represents the right rotary void rotate (node* &o,int d) {Node *k=o->ch[d^1];
    o->ch[d^1]=k->ch[d];
    k->ch[d]=o;
    O->maintain ();
    K->maintain ();
O=k; } void INsert (node* &o,int x) {if (O==null) o=new node (x); else{int d= (x<o->v?0:1);//Do not use CMP functions, possibly with the same node
        Insert (O-&GT;CH[D],X);
    if (o->ch[d]->r>o->r) rotate (o,d^1);
} o->maintain ();
    } void Remove (node* &o,int x) {int d=o->cmp (x);
        if (d==-1) {Node *u=o;
            if (o->ch[0]!=null&&o->ch[1]!=null) {int d2= (O->ch[0]->r > o->ch[1]->r?1:0);
            Rotate (O,D2);
        Remove (o->ch[d2],x);
            } else{if (o->ch[0]==null) o=o->ch[1];
            else o=o->ch[0];
        Delete u;
    } else{Remove (o->ch[d],x);

} if (O!=null) O->maintain ();
const int MAXC=500000+10;
    struct Command {char type;

int x,p;//According to type,p representing K or v}COMMAND[MAXC];
const int MAXN=20000+10;

const int MAXM=60000+10;
int n,m;
int WEIGHT[MAXN];

int FROM[MAXM],TO[MAXM],REMOVED[MAXM];
And check the set of related int PA[MAXN]; int Findset (int x) {return pa[x]!=x?pa[x]=findset (Pa[x]): x;}

Rank tree related Node *ROOT[MAXN]; K Large value int kth (node* o,int k) {if (o==null| | k<=0| |
    K>o->s) return 0;
    int s= (o->ch[1]==null?0:o->ch[1]->s);
    if (k==s+1) return o->v;
    else if (k<=s) return kth (O-&GT;CH[1],K);
else return kth (o->ch[0],k-s-1);
    } void MergeTo (node* &src,node* &dest) {if (src->ch[0]!=null) mergeto (src->ch[0],dest);
    if (src->ch[1]!=null) mergeto (src->ch[1],dest);
    Insert (DEST,SRC-&GT;V);
    Delete src;
Src=null;
    } void Removetree (node* &x) {if (x->ch[0]!=null) Removetree (x->ch[0));
    if (x->ch[1]!=null) Removetree (x->ch[1]);
    Delete x;
X=null;
    }//Main program related void Add_edge (int x) {int u=findset (from[x)), V=findset (To[x]);
            if (u!=v) {if (root[u]->s<root[v]->s) {pa[u]=v;
        MergeTo (Root[u],root[v]);
            } else{Pa[v]=u;
    MergeTo (Root[v],root[u]);    {}} int query_cnt;

Long Long Query_tot;
    void query (int x,int k) {query_cnt++;
Query_tot+=kth (Root[findset (x)],k);
    } void change_weight (int x,int v) {int u=findset (x);
    Remove (root[u],weight[x]);
    Insert (ROOT[U],V);
Weight[x]=v;
    int main () {int kase=0;
        while (scanf ("%d%d", &n,&m) ==2&&n) {for (int i=1;i<=n;i++) scanf ("%d", &weight[i]);
        for (int i=1;i<=m;i++) scanf ("%d%d", &from[i],&to[i));

        memset (removed,0,sizeof (removed));
        Read command int c=0; for (;;)
            {char type;
            int x,p=0,v=0;
            scanf ("%c", &type);
            if (type== ' E ') break;
            scanf ("%d", &x);
            if (type== ' D ') removed[x]=1;
            if (type== ' Q ') scanf ("%d", &p);
                if (type== ' C ') {scanf ("%d", &v);
                P=WEIGHT[X];
            Weight[x]=v;
      } command[c++]= (command) {type,x,p};  }//Final figure for (int i=1;i<=n;i++) {pa[i]=i;
            if (root[i]!=null) Removetree (Root[i]);
        Root[i]=new Node (Weight[i]);
        for (int i=1;i<=m;i++) {if (!removed[i]) Add_edge (i);
        }//reverse operation Query_cnt=query_tot=0;
            for (int i=c-1;i>=0;i--) {if (command[i].type== ' D ') Add_edge (command[i].x);
            if (command[i].type== ' C ') change_weight (COMMAND[I].X,COMMAND[I].P);
        if (command[i].type== ' Q ') query (COMMAND[I].X,COMMAND[I].P);
    printf ("Case%d:%.6lf\n", ++kase,query_tot/(double) query_cnt);
return 0; }




Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.