BZOJ 4919: [Lydsy1706月賽]大根堆 啟發式合並
阿新 • • 發佈:2019-04-20
bound 排序 線段樹 gist digi char insert dfs ext
我不會告訴你這是線段樹合並的好題的。。。
好吧我們可以搞一個multiset在dfs時求出LIS(自帶二分+排序)進行啟發式合並,輕松加愉悅。。。
#include<cstdio> #include<iostream> #include<set> const int N=200010; #define R register int using namespace std; inline int g() { R ret=0; register char ch; while(!isdigit(ch=getchar())); do ret=ret*10+(ch^48); while(isdigit(ch=getchar())); return ret; } int n,m,cnt; multiset<int>s[N]; int vr[N<<1],nxt[N<<1],fir[N],w[N]; inline void add(int u,int v) {vr[++cnt]=v,nxt[cnt]=fir[u],fir[u]=cnt;} inline void dfs(int u) { for(R i=fir[u];i;i=nxt[i]) { R v=vr[i]; dfs(v);if(s[u].size()<s[v].size()) swap(s[u],s[v]); for(multiset<int>::iterator it=s[v].begin();it!=s[v].end();++it) s[u].insert(*it); } multiset<int>::iterator it=s[u].lower_bound(w[u]); if(it!=s[u].end()) s[u].erase(it); s[u].insert(w[u]); } signed main() { n=g(); for(R i=1,fa;i<=n;++i) { w[i]=g(),fa=g(); if(i==1) continue; add(fa,i); } dfs(1); printf("%d\n",s[1].size()); }
2019.04.20
BZOJ 4919: [Lydsy1706月賽]大根堆 啟發式合並