【UNR #1】奇怪的线段树

SOL:

   好像可以贪心啊,一颗树的左儿子的右儿子和右儿子的左儿子合并。其他递归处理。

#pragma GCC optimize("-Ofast")
#include<bits/stdc++.h>
using namespace std;
int n,lx,rx,mx,ux,ans;
int sol(int op,int l,int r,int &lx,int &rx,int &mx,int &ux) {
    int x; scanf("%d",&x);
    if (!op&&x) {puts("OwO");exit(0);}//it->fa=white && it=black is impossible
    if (l<r){
        int mid,ll,rr,l1,r1,l2,r2,m1,m2,u1,u2;
        scanf("%d",&mid);
        ll=sol(x,l,mid,l1,r1,m1,u1);
        rr=sol(x,mid+1,r,l2,r2,m2,u2);
        int mn=min(r1,l2); //it->son[0]->son[1] and it->son[1]->son[0] merge fisrt
        rx=r1-mn,lx=l2-mn; ans+=mn; ux=mn;
        if (!ll) {ans+=lx; lx=0; } // it->son[0] can't merge
        if (!rr) {ans+=rx; rx=0; }
        if (m1&&!l2) {
            if (u2) {u2--; ans--; ++lx; ++rx;}// as the father of seq so cancel the hypothesis
            else ++lx;
        } 
        if (m2&&!r1) {
            if (u1) {u1--; ans--; ++lx; ++rx;}
            else ++rx;
        }
        if (!ll&&!rr) mx=x; else mx=0; //whether this seq can merge
        lx+=l1; rx+=r2;
        if (ll) ux+=u2; if (rr) ux+=u1; // ux's mean is the number of merged seq 
    }  else {lx=rx=ux=0; mx=x;}
    return x;
}
signed main () {
//    freopen("u2.in","r",stdin);
    scanf("%d",&n);
    sol(1,1,n,lx,rx,mx,ux);
    printf("%d",ans+lx+rx+mx);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/rrsb/p/9335776.html