1. 程式人生 > >【bzoj3227】紅黑樹

【bzoj3227】紅黑樹

發現 blog ret amp 這樣的 spa 兩個 include log

神TM的紅黑樹,其實本質上應該還是一種樹dp的問題……

一開始想了一個比較裸的樹dp,後來發現還有更強的做法。

每個前端黑節點是看作一個物品,然後這就是很典型的樹形dp的問題。

不過可以這麽考慮,考慮怎麽縮小問題的範圍。

我們可以把黑色節點的連通塊縮成一個點,這樣的話就要考慮三個情況:

  1. 直接合並兩個相鄰的黑色節點
  2. 將三個黑節點合並為一紅一黑
  3. 將四個黑節點合並為兩紅一黑

所以直接貪心就能做。

#include<bits/stdc++.h>
using namespace std;
int n,m,ans;
inline int read(){
    int f=1,x=0;char
ch; do{ch=getchar();if(ch==-)f=-1;}while(ch<0||ch>9); do{x=x*10+ch-0;ch=getchar();}while(ch>=0&&ch<=9); return f*x; } int main(){ n=read();m=n+1; while(m>1){if(m&1)ans++;m>>=1;} printf("%d\n",ans); m=n+1;ans=0; while(m>1){
if(m==2)ans++; if((m&3)==1)ans+=(m>>2)*2-1,m>>=2,m++; else if((m&3)==2)ans+=(m>>2)*2,m>>=2,m++; else if((m&3)==3)ans+=(m>>2)*2+1,m>>=2,m++; else if(!(m&3))ans+=(m>>2)*2,m>>=2; } printf("%d\n
",ans); }

【bzoj3227】紅黑樹