2333?

先记一下吧,这题现在全部都是照着题解做的,因为怎么改都改不出来,只好对着题解改,以后还要再做过

以后再也不用指针了!太恶心了!空指针可不止直接特判那么简单啊,竟然还要因为空指针写奇怪的分类讨论!

没错,就是那个诡异的55和63行。由于要返回删除x后x所在树的新根,要分类讨论:如果x是根且其两个子节点合并后为空,那么去掉x后新树树根为空;如果x是根且其两个子节点合并后不为空,那么去掉x后新树树根为两个子节点合并后的;如果x不是根,那么去掉x后新树树根为原来的find(x)。

另外,打了注释号的(不管是空注释还是被注释掉的语句)都表示此处出过错

 #include<cstdio>
#include<algorithm>
#include<set>
using namespace std;
multiset<int> sx;
void erase(int x)
{
//if(sx.find(x)!=sx.end())
sx.erase(sx.find(x));
}
struct Node
{
int data;int addv;
Node *ch[],*fa;
void pd()
{
if(addv)
{
if(ch[]) ch[]->addv+=addv,ch[]->data+=addv;
if(ch[]) ch[]->addv+=addv,ch[]->data+=addv;
addv=;//
}
}
}nodes[];
Node* find(Node* x)//
{
if(x==NULL) return x;//
while(x->fa) x=x->fa;
return x;
}
Node* merge(Node* a,Node* b)
{
if(!a) return b;
if(!b) return a;
//a->pd();b->pd();
if(a->data < b->data) swap(a,b);
a->pd();
a->ch[]=merge(a->ch[],b);
if(a->ch[])/**/ a->ch[]->fa=a;
swap(a->ch[],a->ch[]);
return a;
}
Node *q[];int q_num;
void solvetag(Node *x)//
{
while(x)q[++q_num]=x,x=x->fa;
//while(x->fa)q[++q_num]=x,x=x->fa;
while(q_num)q[q_num--]->pd();
}
Node* del(Node *x)//删除x,将x较大的儿子提上来,并返回它所在集合的新根节点
{
//if(x==NULL) return x;//''
solvetag(x);
Node *t=merge(x->ch[],x->ch[]),*f=x->fa,*rt;
rt=find(x);if(rt==x) rt=NULL;//
x->ch[]=x->ch[]=x->fa=NULL;
if(f)//
{
if(x==f->ch[]) f->ch[]=t;
else f->ch[]=t;
}
if(t)/**/ t->fa=f;
if(t) rt=find(t);//
return rt;
}
void add(Node *x,int val)
{
//if(x==NULL) return;
solvetag(x);
erase(find(x)->data);
//find(x)->data+=val;
x->data+=val;Node *t=del(x);
sx.insert(merge(x,t)->data);//puts("t1");
}
void hadd(Node *x,int val)
{
//if(x==NULL) return;//'
Node *p=find(x);
erase(p->data);
p->addv+=val;p->data+=val;
sx.insert(p->data);
}
int n,m,addx,Q;
char tmp[];
int main()
{
int i,t,x,y,v;Node *fx,*fy;
scanf("%d",&n);
for(i=;i<=n;i++)
{
scanf("%d",&t);
nodes[i].data=t;
//nodes[i].upd();
sx.insert(t);
}
scanf("%d",&Q);
//int axx=0;
while(Q--)
{
scanf("%s",tmp);
if(tmp[]=='U')
{
scanf("%d%d",&x,&y);
fx=find(nodes+x);fy=find(nodes+y);
if(fx==fy) continue;
//solvetag(nodes+x);solvetag(nodes+y);
if(merge(fx,fy)==fx) erase(fy->data);
else erase(fx->data);
}
else if(tmp[]=='A')
{
if(tmp[]=='')
{
scanf("%d%d",&x,&v);
add(nodes+x,v); }
else if(tmp[]=='')
{
scanf("%d%d",&x,&v);
hadd(nodes+x,v);
}
else if(tmp[]=='')
{
scanf("%d",&v);
addx+=v;
}
}
else if(tmp[]=='F')
{
//axx++;
//if(axx==54) printf(" %c ",tmp[1]);
if(tmp[]=='')
{
scanf("%d",&x);
solvetag(nodes+x);
printf("%d\n",nodes[x].data+addx);
}
else if(tmp[]=='')
{
scanf("%d",&x);
//solvetag(nodes+x);
printf("%d\n",find(nodes+x)->data+addx);
}
else if(tmp[]=='')
{
printf("%d\n",*(--sx.end())+addx);
} }
}
return ;
}

另外:本来是想不到去写斜堆的,因为斜堆并不保证任何意义上的平衡,如果用这个在节点上维护附加信息,那么标记传递还有找根什么的复杂度应该是假的。然而实际应用发现...并没有问题?仍然不会分析

另外:把堆合并改成非旋treap里面的样子,也可以过,而且用时几乎完全一样(只差几ms)(然而去掉swap两个子节点就不能了,或者将非旋treap合并里面一些对正确性无关紧要的东西乱改一下也不行,这次跟洛谷上某道可并堆模版不一样了...),说明非旋treap里面堆合并跟一般斜堆合并写法本质应该没有区别(只是保证中序遍历不变)。然而并不会分析?

另外:虽然不交换是错的,但是随机怎么摆却是对的!实际效果是只比斜堆慢了一点点。而且,即使斜堆真的会被卡随机堆也不可能被卡...应该吧

就比如这样

 #include<cstdio>
#include<algorithm>
#include<set>
using namespace std;
multiset<int> sx;
inline int rd()
{
static int x=;
return x=(48271LL*x+)%;
}
void erase(int x)
{
//if(sx.find(x)!=sx.end())
sx.erase(sx.find(x));
}
struct Node
{
int data;int addv;
Node *ch[],*fa;
void pd()
{
if(addv)
{
if(ch[]) ch[]->addv+=addv,ch[]->data+=addv;
if(ch[]) ch[]->addv+=addv,ch[]->data+=addv;
addv=;//
}
}
}nodes[];
Node* find(Node* x)//
{
if(x==NULL) return x;//
while(x->fa) x=x->fa;
return x;
}
Node* merge(Node* a,Node* b)
{
if(!a) return b;
if(!b) return a;
//a->pd();b->pd();
if(a->data < b->data) swap(a,b);
a->pd();
if(rd()%)
{
a->ch[]=merge(a->ch[],b);
if(a->ch[]) a->ch[]->fa=a;
}
else
{
a->ch[]=merge(a->ch[],b);
if(a->ch[]) a->ch[]->fa=a;
}
return a; }
Node *q[];int q_num;
void solvetag(Node *x)//
{
while(x)q[++q_num]=x,x=x->fa;
//while(x->fa)q[++q_num]=x,x=x->fa;
while(q_num)q[q_num--]->pd();
}
Node* del(Node *x)//删除x,将x较大的儿子提上来,并返回它所在集合的新根节点
{
//if(x==NULL) return x;//''
solvetag(x);
Node *t=merge(x->ch[],x->ch[]),*f=x->fa,*rt;
rt=find(x);if(rt==x) rt=NULL;//
x->ch[]=x->ch[]=x->fa=NULL;
if(f)//
{
if(x==f->ch[]) f->ch[]=t;
else f->ch[]=t;
}
if(t)/**/ t->fa=f;
if(t) rt=find(t);//
return rt;
}
void add(Node *x,int val)
{
//if(x==NULL) return;
solvetag(x);
erase(find(x)->data);
//find(x)->data+=val;
x->data+=val;Node *t=del(x);
sx.insert(merge(x,t)->data);//puts("t1");
}
void hadd(Node *x,int val)
{
//if(x==NULL) return;//'
Node *p=find(x);
erase(p->data);
p->addv+=val;p->data+=val;
sx.insert(p->data);
}
int n,m,addx,Q;
char tmp[];
int main()
{
int i,t,x,y,v;Node *fx,*fy;
scanf("%d",&n);
for(i=;i<=n;i++)
{
scanf("%d",&t);
nodes[i].data=t;
//nodes[i].upd();
sx.insert(t);
}
scanf("%d",&Q);
//int axx=0;
while(Q--)
{
scanf("%s",tmp);
if(tmp[]=='U')
{
scanf("%d%d",&x,&y);
fx=find(nodes+x);fy=find(nodes+y);
if(fx==fy) continue;
//solvetag(nodes+x);solvetag(nodes+y);
if(merge(fx,fy)==fx) erase(fy->data);
else erase(fx->data);
}
else if(tmp[]=='A')
{
if(tmp[]=='')
{
scanf("%d%d",&x,&v);
add(nodes+x,v); }
else if(tmp[]=='')
{
scanf("%d%d",&x,&v);
hadd(nodes+x,v);
}
else if(tmp[]=='')
{
scanf("%d",&v);
addx+=v;
}
}
else if(tmp[]=='F')
{
//axx++;
//if(axx==54) printf(" %c ",tmp[1]);
if(tmp[]=='')
{
scanf("%d",&x);
solvetag(nodes+x);
printf("%d\n",nodes[x].data+addx);
}
else if(tmp[]=='')
{
scanf("%d",&x);
//solvetag(nodes+x);
printf("%d\n",find(nodes+x)->data+addx);
}
else if(tmp[]=='')
{
printf("%d\n",*(--sx.end())+addx);
} }
}
return ;
}

我差点忘了一件事,就是相同权值的在堆里顺序无所谓,merge两个参数先后也是无所谓的。

bzoj2333[SCOI2011]棘手的操作 洛谷P3273 [SCOI2011]棘手的操作的更多相关文章

  1. 洛谷P3273 [SCOI2011] 棘手的操作 [左偏树]

    题目传送门 棘手的操作 题目描述 有N个节点,标号从1到N,这N个节点一开始相互不连通.第i个节点的初始权值为a[i],接下来有如下一些操作: U x y: 加一条边,连接第x个节点和第y个节点 A1 ...

  2. 洛谷P3273 [SCOI2011]棘手的操作

    题目描述 有N个节点,标号从1到N,这N个节点一开始相互不连通.第i个节点的初始权值为a[i],接下来有如下一些操作:U x y: 加一条边,连接第x个节点和第y个节点A1 x v: 将第x个节点的权 ...

  3. BZOJ2330或洛谷3275 [SCOI2011]糖果

    BZOJ原题链接 洛谷原题链接 很明显的差分约束,但数据范围较大,朴素\(SPFA\)判正环求解会\(T\)(理论上如此,但我看到有挺多人用朴素的还跑得挺快..),所以需要优化. 我们所建立的有向图中 ...

  4. 洛谷P3275 [SCOI2011]糖果(差分约束,最长路,Tarjan,拓扑排序)

    洛谷题目传送门 差分约束模板题,等于双向连0边,小于等于单向连0边,小于单向连1边,我太蒻了,总喜欢正边权跑最长路...... 看遍了讨论版,我是真的不敢再入复杂度有点超级伪的SPFA的坑了 为了保证 ...

  5. AC日记——[HAOI2015]树上操作 洛谷 P3178

    题目描述 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个操作,分为三种:操作 1 :把某个节点 x 的点权增加 a .操作 2 :把某个节点 x 为根的子树中所有点的点权都增加 ...

  6. bzoj2333 [SCOI2011]棘手的操作(洛谷3273)

    题目描述 有N个节点,标号从1到N,这N个节点一开始相互不连通.第i个节点的初始权值为a[i],接下来有如下一些操作:U x y: 加一条边,连接第x个节点和第y个节点A1 x v: 将第x个节点的权 ...

  7. 洛谷.3273.[SCOI2011]棘手的操作(左偏树)

    题目链接 还是80分,不是很懂. /* 七个操作(用左偏树)(t2表示第二棵子树): 1.合并:直接合并(需要将一个t2中原有的根节点删掉) 2.单点加:把这个点从它的堆里删了,加了再插入回去(有负数 ...

  8. 【POJ 3159】Candies&&洛谷P3275 [SCOI2011]糖果

    来补一下自己很久以前那个很蒟蒻很蒟蒻的自己没有学懂的知识 差分约束,说白了就是利用我们在求最短路的一个\(relax\)操作时的判断的原理 \[dis[v]>dis[u]+disj(u,v)\] ...

  9. bzoj 1858: [Scoi2010]序列操作 || 洛谷 P2572

    记一下:线段树占空间是$2^{ceil(log2(n))+1}$ 这个就是一个线段树区间操作题,各种标记的设置.转移都很明确,只要熟悉这类题应该说是没有什么难度的. 由于对某区间set之后该区间原先待 ...

随机推荐

  1. python执行

    转载:https://www.cnblogs.com/zflibra/p/4180796.html

  2. 从日志文件解决ArcGIS Server性能低下问题的步骤(1)

    日志级别和结构 http://www.cnblogs.com/fortoday/archive/2011/03/30/2000348.html ArcGIS Server日志文件分为几个记录级别: 无 ...

  3. 使用Android SwipeRefreshLayout了解Android的嵌套滑动机制

    SwipeRefreshLayout 是在Android Support Library, revision 19.1.0加入到support v4库中的一个下拉刷新控件,关于android的下拉刷新 ...

  4. JAVA学习(一):Java介绍及其平台、开发环境的配置与搭建

    Java介绍及其平台.开发环境的配置与搭建 1.Java的介绍 Java是一种面向对象的编程语言,具有跨平台.可移植.分布式.简单.可扩展等诸多特性.Java能够进行桌面应用.Web应用.分布式系统及 ...

  5. 【转】JavaScript错误处理和堆栈追踪

    原文: https://www.cnblogs.com/caoru/p/6699583.html --------------------------------------------------- ...

  6. Java中常见的排序算法

    这是我摘取的一段英文资料.我认为学习算法之前,对各种排序得有个大致的了解: Sorting algorithms are an important part of managing data. At ...

  7. react 项目中 引入 bootstrap

    react-bootstrap是一个非常受欢迎的针对react封装过的bootstrap,它本身不包含css,所以也是需要使用bootstrap原生库. 在create-react-app建的项目目录 ...

  8. MySQL基础笔记(四) 索引

    一.什么是索引 索引(Index),可以看作一个指针,指向表里的数据.当数据库没有索引时,查找信息通常是全表扫描:使用了索引,它就会直接引导到数据在表里的准确物理位置. 优点:索引的主要目的是提高数据 ...

  9. html2canvas 导出包含滚动条的内容

    import html2canvas from 'html2canvas'; exportPDF() { // 导出为 pdf let dom = document.querySelector('yo ...

  10. Nyquist–Shannon sampling theorem 采样定理

    Nyquist–Shannon sampling theorem - Wikipedia https://en.wikipedia.org/wiki/Nyquist%E2%80%93Shannon_s ...