题目描述

真的是个很棘手的操作。。

注意每删除一个点,就需要clear一次。

#include<complex>
#include<cstdio>
using namespace std;
const int N=3e5+;
int n,m,rot,add;
//add记录所有节点增加的权值
int q[N<<];
inline int qread()
{
int x=,j=;
char ch=getchar();
while(ch<'' || ch>''){if(ch=='-')j=-;ch=getchar();}
while(ch>='' && ch<=''){x=x*+ch-'';ch=getchar();}
return x*j;
}
struct Leftist
{
int fat[N],son[N][],key[N],dis[N],mark[N];
void clear(int x)
{
fat[x]=son[x][]=son[x][]=;
}
void PushDown(int x)
{
if(!mark[x])return;
if(son[x][])
{
key[son[x][]]+=mark[x];
mark[son[x][]]+=mark[x];
}
if(son[x][])
{
key[son[x][]]+=mark[x];
mark[son[x][]]+=mark[x];
}
mark[x]=;
}
int Merge(int a,int b)
{
if(!a || !b)return a+b;
if(key[a]<key[b])swap(a,b);
PushDown(a);
son[a][]=Merge(son[a][],b);
fat[son[a][]]=a;
if(dis[son[a][]]>dis[son[a][]])swap(son[a][],son[a][]);
dis[a]=dis[son[a][]]+;
return a;
}
int Sum(int x)
{
int res=;
while(x=fat[x])res+=mark[x];
return res;
}
int Top(int x)
{
while(fat[x])x=fat[x];
return x;
}
int Pop(int x)
{
PushDown(x);
int q=fat[x],p=Merge(son[x][],son[x][]);
if(q)son[q][son[q][]==x]=p;
fat[p]=q;
while(q)
{
if(dis[son[q][]]>dis[son[q][]])
swap(son[q][],son[q][]);
if(dis[q]==dis[son[q][]]+)return rot;
dis[q]=dis[son[q][]]+;
p=q;q=fat[q];
}
return p;
}
int AddPoint(int x,int v)
{
int t=Top(x);
if(t==x)
if(!son[x][] && !son[x][])
{
key[x]+=v;
return x;
}
else
if(son[x][])t=son[x][];
else t=son[x][];
Pop(x);
key[x]+=v+Sum(x);
clear(x);
return Merge(Top(t),x);
}
int Build()
{
int head=,tail=;
for(int i=;i<=n;i++)
q[++tail]=i;
int x,y;
while(tail-head)
{
x=q[head++];y=q[head++];
q[++tail]=Merge(x,y);
}
return q[head];
}
}t1,t2;
//对于F3操作,需要把所有堆的根拿出来建一个新的堆
//新开一棵t2来维护这些点
int main()
{
scanf("%d",&n);
for(int i=;i<=n;i++)
t1.key[i]=t2.key[i]=qread();
rot=t2.Build();
char c[];int x,y,r1,r2;
scanf("%d",&m);
while(m--)
{
scanf("%s",c);
if(c[]=='U')
{
x=qread();y=qread();
r1=t1.Top(x);r2=t1.Top(y);
if(r1!=r2)
{
int tmp=t1.Merge(r1,r2);
if(tmp==r1)t2.Pop(r2);
else t2.Pop(r1);
/*
合并时,若树a并到了b上,则将a从第二棵树中删除,反之则删除b
被删去的点还是可能会成为最大值的,可它已经被删除了....
它再次成为最大值只有可能是在A1操作,将它再插入就好了
*/
}
}
else if(c[]=='A' && c[]=='')
{
x=qread();y=qread();
rot=t2.Pop(t1.Top(x));
int tmp=t1.AddPoint(x,y);
t2.key[tmp]=t1.key[tmp];
t2.clear(tmp);
rot=t2.Merge(rot,tmp);
}
else if(c[]=='A' && c[]=='')
{
x=qread();y=qread();
r1=t1.Top(x);
rot=t2.Pop(r1);
//整个联通块都+y,不影响堆的性质,但mark不能及时下传,所以仍要把根删去后再插入
t1.key[r1]+=y;t1.mark[r1]+=y;
t2.key[r1]=t1.key[r1];
t2.clear(r1);
rot=t2.Merge(r1,rot);
}
else if(c[]=='A' && c[]=='')add+=qread();
else if(c[]=='F' && c[]=='')
{
x=qread();
printf("%d\n",t1.key[x]+add+t1.Sum(x));
}
else if(c[]=='F' && c[]=='')
{
x=qread();
printf("%d\n",t1.key[t1.Top(x)]+add);
}
else printf("%d\n",t2.key[rot]+add);
}
return ;
}

BZOJ 2333: [SCOI2011]棘手的操作的更多相关文章

  1. BZOJ 2333: [SCOI2011]棘手的操作 可并堆 左偏树 set

    https://www.lydsy.com/JudgeOnline/problem.php?id=2333 需要两个结构分别维护每个连通块的最大值和所有连通块最大值中的最大值,可以用两个可并堆实现,也 ...

  2. BZOJ 2333 SCOI2011 棘手的操作 并查集+可并堆

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2333 ..题意概述就不写了,各位老爷如果是看着玩的可以去搜一下,如果是做题找来的也知道题干 ...

  3. bzoj 2333 [SCOI2011]棘手的操作 —— 可并堆

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2333 稍微复杂,参考了博客:http://hzwer.com/5780.html 用 set ...

  4. BZOJ 2333 [SCOI2011]棘手的操作 (可并堆)

    码农题.. 很显然除了两个全局操作都能用可并堆完成 全局最大值用个multiset记录,每次合并时搞一搞就行了 注意使用multiset删除元素时 如果直接delete一个值,会把和这个值相同的所有元 ...

  5. 2333: [SCOI2011]棘手的操作[写不出来]

    2333: [SCOI2011]棘手的操作 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1979  Solved: 772[Submit][Stat ...

  6. 2333: [SCOI2011]棘手的操作[离线线段树]

    2333: [SCOI2011]棘手的操作 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2325  Solved: 909[Submit][Stat ...

  7. 2333: [SCOI2011]棘手的操作[我不玩了]

    2333: [SCOI2011]棘手的操作 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1979  Solved: 772[Submit][Stat ...

  8. 【BZOJ】2333: [SCOI2011]棘手的操作

    http://www.lydsy.com/JudgeOnline/problem.php?id=2333 题意: 有N个节点,标号从1到N,这N个节点一开始相互不连通.第i个节点的初始权值为a[i], ...

  9. 【BZOJ 2333 】[SCOI2011]棘手的操作(离线+线段树)

    2333: [SCOI2011]棘手的操作 Description 有N个节点,标号从1到N,这N个节点一开始相互不连通.第i个节点的初始权值为a[i],接下来有如下一些操作: U x y: 加一条边 ...

随机推荐

  1. AS3中 is,as,typeof的区别

    AS3中 is,as,typeof的区别 . var my_num:Number=9;trace(typeof my_num);var my_object:Array=["语文", ...

  2. Python之TensorFlow的卷积神经网络-5

    一.卷积神经网络(Convolutional Neural Networks, CNN)是一类包含卷积计算且具有深度结构的前馈神经网络(Feedforward Neural Networks),是深度 ...

  3. ADO.NET 五(DataAdapter 与 DataSet)

    在执行对表中数据的查询时还能将数据保存到 DataSet 中,但需要借助 DataAdapter 类来实现. 在实际应用中,DataAdapter 与 DataSet 是在查询操作中使用最多的类. 此 ...

  4. 使用jQuery开发messager消息框插件

    1.插件使用 首先引入jquery库,然后引入dialog.js.dialog.css.messager.js.messager.css,如下: <script type="text/ ...

  5. bsd pkg install gcc gmake cmake gdb cgdb

    bsd pkg install gcc gmake cmake gdb cgdb 安装pkg帮助文档并查看文档# pkg help install# man pkg-install # pkg sea ...

  6. 【洛谷 P4137】 Rmq Problem / mex(主席树)

    题目链接 容易发现,可能答案只有\(0\).每个数,每个数\(+1\) 于是把这\(2n+1\)个数建立一个权值线段树,可持久化一下,每个节点记录这个子树中最后加入数加入的时间的最小值\(latest ...

  7. 了解Django之前

      什么是web应用? 通俗地讲,就是通过浏览器访问一个网址,该网站从后台调取数据,然后把相应的界面展示给用户这样的一个过程. 什么是HTTP协议? 即超文本传输协议:规定了客户端与服务端消息传输的格 ...

  8. vue中如何判断checkbox是否选中

    console.log(event.target.checked)     例:  

  9. 【雅思】【绿宝书错词本】List37~48

    List 37 ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ List 38 ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ List 39 ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ...

  10. uboot使用脚本

    使用mkimage命令 # mkimage -A ARM -O linux -T script -C none -n "script" -d *.sh *.img # tftp x ...