【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; }