Luogu P3521 [POI2011]ROT-Tree Rotations

Posted maomao9173

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Luogu P3521 [POI2011]ROT-Tree Rotations相关的知识,希望对你有一定的参考价值。

题目链接 (Click) (Here)

线段树合并,没想到学起来意外的很简单,一般合并权值线段树。

建树方法和主席树一致,即动态开点。合并方法类似于(FHQ)的合并,就是把两棵树的信息整合到一个里面。暂时没写过定义域不同的线段树合并,具体方法也想象不出来,写到了再详细讲吧。

算法复杂度:均摊(O(NlogN)),实际空间时间复杂度都不够稳定,需要谨慎使用。

#include <bits/stdc++.h>
using namespace std;

const int N = 200010;
#define ll long long
#define mid ((l + r) >> 1)

int n, pos;
ll ANS = 0, ans1 = 0, ans2 = 0;

struct node{
    int sumn, ls, rs;
}t[N << 5];

int cnt = 0; // 

void update (int &nown, int l, int r) { 
    if (nown == 0) nown = ++cnt;
    t[nown].sumn++;
    if (l != r) {
        if (pos <= mid) {
            update (t[nown].ls, l, mid);
        } else {
            update (t[nown].rs, mid + 1, r);
        }
    }
}   

void merge (int &lx, int rx) {
    if (lx * rx == 0) {
        lx = lx + rx; 
        return;
    }
    t[lx].sumn += t[rx].sumn;
    ans1 += 1LL * t[t[lx].rs].sumn * t[t[rx].ls].sumn;
    ans2 += 1LL * t[t[lx].ls].sumn * t[t[rx].rs].sumn;
    merge (t[lx].ls, t[rx].ls);
    merge (t[lx].rs, t[rx].rs);
}

void solve (int &x) {
    int t, ls, rs; x = 0;
    cin >> t;
    if(t == 0) { 
        solve (ls); 
        solve (rs);
        ans1 = ans2 = 0;
        merge (x = ls, rs);
        ANS += min (ans1, ans2);
    } else {
        pos = t;
        update (x, 1, n);
    }
}

int main () {
    cin >> n;
    int t = 0;
    solve (t);
    cout << ANS << endl;
    return 0;
}

以上是关于Luogu P3521 [POI2011]ROT-Tree Rotations的主要内容,如果未能解决你的问题,请参考以下文章

P3521 [POI2011]ROT-Tree Rotations

P3521 [POI2011]ROT-Tree Rotations

题解 P3521 [POI2011]ROT-Tree Rotations

LuoguP3521 [POI2011]ROT-Tree Rotations

bzoj 2212[POI2011]ROT-Tree Rotations - 线段树合并

线段树合并(POI2011ROT-Tree Rotations)