[bzoj4919]大根堆——set启发式合并
2018-04-02 17:01
351 查看
题目大意:
给定一棵n个节点的有根树,编号依次为1到n,其中1号点为根节点。每个点有一个权值v_i。你需要将这棵树转化成一个大根堆。确切地说,你需要选择尽可能多的节点,满足大根堆的性质:对于任意两个点i,j,如果i在树上是j的祖先,那么vi>vjvi>vj。
请计算可选的最多的点数,注意这些点不必形成这棵树的一个连通子树。
思路:
发现这其实就是在求书上的最长上升子序列,考虑我们在求树为一条链时的情况,从前往后扫,并且使用了一个单调队列,只有当后一个节点严格大于队列中最大的元素的时候,才可以把这个元素新加进去,如果不是严格大于,我们会二分单调队列中第一个大于等于它的元素,然后将它替换,当我们把这种方法运用到树上的时候,发现同样也是成立的,只需要把一个节点的所有子节的单调队列全部合并之后,再像之前那样的做法,添加这个元素就可以了。如果不加任何优化,时间和空间上面都是过不去,所以我们使用启发式合并,并且每次合并之后删除这个set。
代码其实非常简短:
/************************************************************** Problem: 4919 User: ylsoi Language: C++ Result: Accepted Time:888 ms Memory:23124 kb ****************************************************************/ #include<iostream> #include<algorithm> #include<cstdio> #include<cstring> #include<cmath> #include<set> using namespace std; void File(){ freopen("bzoj4919.in","r",stdin); freopen("bzoj4919.out","w",stdout); } #define REP(i,a,b) for(register int i=a;i<=b;++i) #define DREP(i,a,b) for(register int i=a;i>=b;--i) #define MREP(i,x) for(register int i=beg[x];i;i=E[i].last) #define ll long long #define inf (0x3f3f3f3f) const int maxn=2e5+10; int n,w[maxn],beg[maxn],cnt,fa[maxn]; struct edge{ int to; int last; }E[maxn*2]; void add(int u,int v){ ++cnt; E[cnt].to=v; E[cnt].last=beg[u]; beg[u]=cnt; } multiset<int>s[maxn]; multiset<int>::iterator it1,it2,it3; void merge(int x,int y){ if(s[x].size()<s[y].size())swap(s[x],s[y]); it1=s[y].begin();it2=s[y].end(); for(;it1!=it2;++it1)s[x].insert(*it1); s[y].clear(); } void dfs(int u){ MREP(i,u){ int v=E[i].to; dfs(v); merge(u,v); } it3=s[u].lower_bound(w[u]); if(it3!=s[u].end())s[u].erase(it3); s[u].insert(w[u]); } int main(){ //File(); scanf("%d",&n); REP(i,1,n){ scanf("%d%d",&w[i],&fa[i]); if(fa[i])add(fa[i],i); } dfs(1); cout<<s[1].size()<<endl; return 0; }
相关文章推荐
- BZOJ4919 [Lydsy1706月赛]大根堆 【dp + 启发式合并】
- BZOJ.4919.[Lydsy1706月赛]大根堆(线段树合并/启发式合并)
- [bzoj4919][Lydsy1706月赛]大根堆【dp】【启发式合并】【stl】
- bzoj4919 大根堆 [启发式合并]
- [BZOJ4919][Lydsy六月份月赛 .C][树上DP][启发式合并]大根堆
- [广义后缀自动机 set启发式合并 || dfs序 树状数组 离线] BZOJ 2780 [Spoj]8093 Sevenk Love Oimaster
- 【BZOJ1483】[HNOI2009]梦幻布丁【启发式合并】【Set】
- 4919: [Lydsy1706月赛]大根堆 multiset 启发式合并 思路
- 【BZOJ4919】[Lydsy六月月赛]大根堆 线段树合并
- bzoj4919 大根堆(线段树合并)
- bzoj 3123(主席树+启发式合并)
- BZOJ1483 梦幻布丁 —— 链表启发式合并
- 【bzoj 1483】梦幻布丁(链表的启发式合并)
- BZOJ 3545 [ONTAK2010]Peaks Treap启发式合并
- BZOJ 1483 HNOI2009 梦幻布丁 链表+启发式合并
- 【bzoj1486】【[HNOI2009]梦幻布丁】启发式链表合并(详解)
- bzoj 3545: [ONTAK2010]Peaks (splay启发式合并)
- [bzoj3123][洛谷P3302] [SDOI2013]森林(树上主席树+倍增lca+启发式合并)
- 【BZOJ】【P3545】【ONTAK2010】【Peaks】【题解】【离线+并查集+平衡树启发式合并】
- 【BZOJ 2733】【HNOI 2012】永无乡 Splay启发式合并