Leftist tree / heap and can study notes

Previous shallow learn about this data structure, but learn with shallow learned did not learn the same. Now going to school again, maybe he did not learn also learn with the same QAQ .

Recommended blog: https://blog.csdn.net/wang3312362136/article/details/80615874

https://blog.csdn.net/pengwill97/article/details/82874235  (Code very good)

 

The name suggests is available and can be combined heap heap can be understood as a data structure can merge two priority queues, and stacks can write good code is the time complexity is also very good (said to be the big brother card to O (n) a) It is a good data structure. And the stack has stack may nature and properties left side. There are common operations to merge two stacks ① ② ③ heap where the number of queries to a query / delete top of the heap element.

 

Template question: Luo Gu P3377 leftist tree

Referring to the above code is the big brother of (scholar of things that can be called ... Keke). But big brother thing Error: Find an element belongs heap when violence is jumping way up, step by step so that jump will be stuck to the O (n), will submit a set of data is the last card in Los Valley . Process optimization approach is the way it should find a path compression , and pay attention to the use of a compression path so when pop elements pop out point to point to the new root .

#include <bits/stdc++.h>
using namespace std;
const int nmax = 1e6 + 7;
const int INF = 0x3f3f3f3f;
struct node {
    int val, lc, rc, dis, fa;
}tree[nmax];
int tot = 0;
int n, m;
void init(int x) {
    for (int i = 0; i <= x; ++i) {
        tree[i].lc = tree[i].rc = tree[i].dis = 0;
        tree[i].fa = i;  // start of each element is the top of the heap 
    } 
} 

int Merge ( int X, int Y) {
     IF (X == 0 ) return Y;
     IF (Y == 0 ) return X;
     IF (Tree [X]. Val> Tree [Y] .val || (Tree [X] .val == Tree [Y] .val && X> Y)) 
        the swap (X, Y);   // Note here combined priority, like precedence priority queue 
    Tree [X] .rc = Merge (Tree [X] .rc, Y); 
    Tree [Tree [X] .rc] .fa = X;
     IF (Tree [Tree [X] .rc] .dis > Tree [Tree [X] .lc] .dis) 
        the swap (Tree [X] .rc, Tree [X] .lc); 
    Tree [X] .disTree = [X] .rc == 0 ? 0 : Tree [Tree [X] .rc] .dis + . 1 ;
     return X; 
} 
int Findset ( int X) {
     return Tree [X] .fa == X X? : Tree [X] = .fa Findset (Tree [X] .fa); // is the top of the stack of fa = x 
}
 // int Findset (int X) {
 //     the while (Tree [X] = .fa! x) { // is the top of the stack of fa = x 
 //         x = Tree [x] .fa;
 //     }
 //     return x;
 // } 
int the Add ( int Val, int x) {   // to stack x new elements val 
    Tree [TOT] .lc = Tree [TOT] .rc = Tree [TOT] .dis = 0 ; 
    Tree [TOT ++] = Val. Val;
     return Merge (TOT - . 1 , X); 
} 
int del ( int X) {
     int L = Tree [X] .lc, = R & lt Tree [X] .rc; 
    Tree [X] .fa = Tree [X] = .lc Tree [X] .rc Tree = [X ] .dis = 0 ; 
    Tree [X] .val = - INF; 
    Tree [L] .fa = L, Tree [R & lt] .fa = R & lt;
     return Tree [X] .fa = Merge (L, R & lt);   / / with path compression, pop out of the point to point to the new root 
} 

int Build () { 
    Queue < int> q;
    for (int i = 1; i <= n; ++i) q.push(i);
    while (!q.empty()) {
        if (q.size() == 1) break;
        else {
            int x = q.front(); q.pop();
            int y = q.front(); q.pop();
            q.push(merge(x, y));
        }
    }
    int finally = q.front(); q.pop();
    return finally;
}

int main() 
{
    scanf("%d %d", &n, &m);
    init(n);
    for (int i = 1; i <= n; ++i) scanf("%d", &tree[i].val);
    int op, a, b;
    for (int i = 1; i <= m; ++i) {
        scanf("%d", &op);
        if (op == 1) {
            scanf("%d %d", &a, &b);
            int xx = findset(a), yy = findset(b);
            if (tree[a].val == -INF || tree[b].val == -INF || xx == yy) {
                continue;
            } else {
                merge(xx, yy);
            }
        } else {
            scanf("%d", &a);
            if (tree[a].val == -INF) {
                printf("-1\n");
            } else {
                int tmp = findset(a);
                printf("%d\n", tree[tmp].val);
                del(tmp);
            }
        }
    }
    return 0;
}
View Code

 

BZOJ 2809 dispatching

The meaning of problems: tree given n points, each point b and a cost value C, then x is selected from a root sum of these points and the cost of less than or equal to m x in the subtree rooted at the selected point as much as possible, to give the value is c [x] * siz [x] (x point value multiplied by the total number of points selected).

Solution: This question is very good, just used to practice hand and can heap. One obvious approach is correct, the tree dfs, dfs calculates the current point x to x in the subtree selected maximum value, if the sum of the current sub-tree takes greater than m, then of course in accordance with the cost point descending removed off until it takes less than m is the answer. Rethinking the discovery process from the bottom up is continuously considered (meaning here is not the point son subtree father subtrees must also not be used because m is fixed!). Then the search process can maintain a heap, then merge the stack from the bottom up, then they would be used to optimize the leftist tree.

#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 7;
const int INF = 0x3f3f3f3f;
typedef long long LL;
struct node {
    int val, lc, rc, dis, fa;
}tree[N];
vector<int> G[N];
int tot = 0;
int n, m,rt,a[N],b[N],c[N];
LL ans=0;
void init(int x) {
    for (int= I 0 ; I <= X; ++ I) { 
        Tree [I] .lc = Tree [I] .rc = Tree [I] .dis = 0 ; 
        Tree [I] .fa = I;   // start each element is the top of the heap 
    } 
} 

int Merge ( int X, int Y) {
     IF (X == 0 ) return Y;
     IF (Y == 0 ) return X;
     IF (Tree [X] .val <Tree [ Y] .val || (Tree [X] .val == Tree [Y] .val && X < Y)) 
        the swap (X, Y);   // Note here combined priority, such priority queue priority 
    tree [x] .rc = merge(tree[x].rc, y);
    tree[tree[x].rc].fa = x;
    if (tree[tree[x].rc].dis > tree[tree[x].lc].dis)
        swap(tree[x].rc, tree[x].lc);
    tree[x].dis = tree[x].rc == 0 ? 0 : tree[tree[x].rc].dis + 1;
    return x;
}
int findset(int x) {  //路径压缩 
    return tree[x].fa==x ? x : tree[x].fa=findset(tree[x].fa); //fa=x的才是堆顶 
}
//int findset(int x) {
//    while (tree[x].fa != x) { //is the top of the stack of fa = x 
 //         x = Tree [x] .fa;
 //     }
 //     return x;
 // } 
int the Add ( int Val, int x) {   // To new stack elements x Val 
    Tree [TOT] .lc = Tree [TOT] .rc = Tree [TOT] .dis = 0 ; 
    Tree [TOT ++] = Val. Val;
     return Merge (TOT - . 1 , X); 
} 
int del ( int X) {
     int L = Tree [X] .lc, = R & lt Tree [X] .rc; 
    Tree [X] .fa = Tree [X] = .lc Tree [X] .rc = Tree [X] .dis = 0 ; 
    Tree [x] .val= - INF; 
    Tree [L] .fa = L, Tree [R & lt] .fa = R & lt;
     return Tree [X] .fa = Merge (L, R & lt);   // with path compression, pop out of the point to point new root 
} 

int Build () { 
    Queue < int > Q;
     for ( int I = . 1 ; I <= n-; ++ I) q.push (I);
     the while (! q.empty ()) {
         IF ( q.size () == . 1 ) BREAK ;
         the else {
             int X = q.front (); q.pop ();
             int Y = q.front(); q.pop();
            q.push(merge(x, y));
        }
    }
    int finally = q.front(); q.pop();
    return finally;
}

LL sum[N]; int siz[N];
void dfs(int x) {
    sum[x]+=b[x]; siz[x]++;
    for (int i=0;i<G[x].size();i++) {
        int y=G[x][i];
        dfs(y);
        sum[x]+=sum[y]; siz[x]+=siz[y];
        int fx=findset(x),fy=findset(y);
        merge(fx,fy);
    }
    while (sum[x]>m) {
        int fx=findset(x);
        sum[x]-=tree[fx].val; del(fx);
        siz[x]--;
    }
    ans=max(ans,(LL)siz[x]*c[x]);
}

int main() 
{
    scanf("%d %d", &n, &m);
    for (int i=1;i<=n;i++) {
        scanf("%d%d%d",&a[i],&b[i],&c[i]);
        if (a[i]==0) rt=i;
        else G[a[i]].push_back(i);
    }
    init(n);
    for (int i = 1; i <= n; ++i) tree[i].val=b[i];
    dfs(rt);
    cout<<ans<<endl;
    return 0;
}
View Code

 

BZOJ 1367 sequence

The meaning of problems: in a given sequence a1 ~ an, seeking a sequence of incremental b1 ~ bn, that abs (a1-b1) + abs (a2-b2) + ... abs (an-bn) is minimized.

Solution: This is https://wenku.baidu.com/view/20e9ff18964bcf84b9d57ba1.html this thesis topic.

Guess you like

Origin www.cnblogs.com/clno1/p/11423254.html