bzoj2333 [SCOI2011]棘手的操作
来源:互联网 发布:全看网软件下载 编辑:程序博客网 时间:2024/05/19 22:01
传送门
事实证明:同时维护并查集和左偏树里的父节点是完全错误的……
题目的实质是要求可并堆(我用的左偏树)支持删除任意点,然后自己就yy了一种删除操作,大致就是把要删除的点先加上所有祖先节点上的标记,然后把它的左右子树合并加到原来的父节点对应的儿子位置上,同时维护父亲。
题目还有一个操作是找所有节点中权值最大的那个,我一开始写了另一个左偏树来维护,结果搞了好久都没调出来,看了黄学长的题解发现STL的妙用于是秒改。。其实这个时候把并查集删掉就能A了。然而我没删,结果每次都RE,GG
总结:
并查集和父节点不要同时维护;(这种暴力查找父节点的复杂度应该和不路径压缩和按秩合并的并查集差不多,但是并不会T,我也不知道为什么,如果有好心人可以在底下留言告诉我,感激不尽)
STL有时能大大简化代码复杂度,一定要灵活使用!
CODE:
#include<set>#include<cstdio>#include<iostream>using namespace std;const int N=3e5+10;struct node{ int num,plus,dis,id; node *ch[2],*fa; inline void pushdown();}pool[N],*t[N],*null;inline void node::pushdown(){ if(plus) { if(ch[0]!=null) ch[0]->plus+=plus,ch[0]->num+=plus; if(ch[1]!=null) ch[1]->plus+=plus,ch[1]->num+=plus; plus=0; }}int n,m,x,y,tot,Plus;multiset<int> s;inline void getnew(int value,int id){ node *now=pool+ ++tot; now->ch[0]=now->ch[1]=now->fa=null; now->num=value,now->id=id; now->dis=1; t[id]=now;}inline int find(int x){ while(t[x]->fa!=null) x=t[x]->fa->id; return x;}int findtag(node *now){ if(now==null) return 0; return findtag(now->fa)+now->plus;}node *merge(node *x,node *y){ if(x==null) return y; if(y==null) return x; if(x->num<y->num) swap(x,y); x->pushdown(),y->pushdown(); x->ch[1]=merge(x->ch[1],y); x->ch[1]->fa=x; if(x->ch[0]->dis<x->ch[1]->dis) swap(x->ch[0],x->ch[1]); x->dis=x->ch[1]->dis+1; return x;}inline node *del(node *now){ node *fa=now->fa,*child=merge(now->ch[0],now->ch[1]); now->ch[0]=now->ch[1]=now->fa=null; if(fa->ch[0]==now) fa->ch[0]=child; else fa->ch[1]=child; child->fa=fa; return t[find(child->id)];}inline void Merge(int x,int y){ x=find(x),y=find(y); if(x==y) return; if(merge(t[x],t[y])==t[x]) s.erase(s.find(t[y]->num)); else s.erase(s.find(t[x]->num));}inline void change(int x,int y){ node *now=t[x];s.erase(s.find(t[find(x)]->num)); now->num+=y+findtag(now->fa);now->pushdown(); s.insert(merge(del(now),now)->num);}inline void add(node *root,int y){ s.erase(s.find(root->num)); root->plus+=y,root->num+=y; s.insert(root->num);}int main(){ null=pool; null->ch[0]=null->ch[1]=null->fa=null; null->dis=-1;t[0]=null; scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&x),getnew(x,i),s.insert(x); scanf("%d",&m); while(m--) { char c=getchar(); while(c<'A'||c>'Z') c=getchar(); if(c=='A') { c=getchar(); if(c=='1') scanf("%d%d",&x,&y),change(x,y); else if(c=='2') scanf("%d%d",&x,&y),add(t[find(x)],y); else scanf("%d",&x),Plus+=x; } else if(c=='F') { c=getchar(); if(c=='1') scanf("%d",&x),printf("%d\n",t[x]->num+findtag(t[x]->fa)+Plus); else if(c=='2') scanf("%d",&x),printf("%d\n",t[find(x)]->num+Plus); else printf("%d\n",*--s.end()+Plus); } else scanf("%d%d",&x,&y),Merge(x,y); } return 0;}
阅读全文
0 0
- bzoj2333: [SCOI2011]棘手的操作
- BZOJ2333: [SCOI2011]棘手的操作
- bzoj2333 [SCOI2011]棘手的操作
- bzoj2333[SCOI2011]棘手的操作
- bzoj2333: [SCOI2011]棘手的操作
- bzoj2333 [SCOI2011]棘手的操作
- 【BZOJ2333】【SCOI2011】棘手的操作 treap合并
- bzoj2333: [SCOI2011]棘手的操作 线段树+离线
- [BZOJ2333][SCOI2011][可并堆]棘手的操作
- bzoj2333: [SCOI2011]棘手的操作(启发式合并做法)
- 【BZOJ2333】【SCOI2011】棘手的操作 可并堆+堆套堆(什么嘛,用个set就好啦)
- [BZOJ2333][SCOI2011]棘手的操作(可并堆||线段树+离线)
- [BZOJ2333][SCOI2011]棘手的操作(可并堆||线段树)
- 【SCOI2011 Day2】棘手的操作
- 【SCOI2011】【线段树】棘手的操作
- BZOJ 2333: [SCOI2011]棘手的操作
- 【左偏树】【bzoj 2333】: [SCOI2011]棘手的操作
- BZOJ 2333 [SCOI2011]棘手的操作
- 哇!这就是Makefile?
- CCF 201703-4 地铁修建(最小生成树 + 并查集)
- Linux帮助命令
- [BZOJ4818][SDOI2017]序列计数(DP+容斥原理+矩乘)
- sum HDU
- bzoj2333 [SCOI2011]棘手的操作
- a链接点击之后出现阴影
- laravel mvc组件创建
- python new方法
- c语言位运算有什么作用
- 已上线三个小程序,需要小程序开发的联系
- 百度第三代Spider是什么?
- 无线Mesh
- CCF 201612-1 中间数