题目描述

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

注意每删除一个点,就需要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. 在Firefox中操作iframe的一个小问题

    在做一个 Web 的打印功能时,需要将被打印的文档写到 iframe 的 document 中. <!doctype html> <html lang="en"& ...

  2. mysql sql 分析

    一.SQL 执行时间分析通过找到执行时间长的 SQL 语句,可以直观的发现数据层的效率问题. 1.通过 show processlist 来查看系统的执行情况mysql> show proces ...

  3. Java中 StringBuffer StringBuilder String 区别

    String       字符串常量   不可变  使用字符串拼接时是不同的2个空间 StringBuffer  字符串变量   可变   线程安全  字符串拼接直接在字符串后追加 StringBui ...

  4. python3.7 64位中安装pygame1.9.3

    1.我是用pip命令来安装的,首先,打开cmd,输入pip,检查电脑中有没有安装这个插件(一般python2.7以上自带pip工具) 2.更新pip工具的命令:python -m pip instal ...

  5. ADO.NET 六(DataRow DataColumn)

    已经介绍了使用 SqlCommand 对象中的 ExecuteNonQuery 方法执行非查询 SQL 语句来实现对数据表的更新操作,使用 DataSet 对象也能实现相同的功能, 并且能节省数据访问 ...

  6. android 常用库的地址--dialog,recycler

    android 弹出框     https://github.com/li-xiaojun/XPopup android  RecyclerViewAdapter     https://github ...

  7. 【洛谷 P2597】 [ZJOI2012]灾难(LCA)

    题目链接 考虑建一棵树,使一个生物灭绝时他的子树都会灭绝,显然这样答案就是以每个点为根的子树大小-1. 为什么原图不是一棵树,因为一个生物可能会以多个生物为食,所以按拓扑序来建树,把每个遍历到的点的父 ...

  8. php后台实现页面跳转的方法-转载

    地址:http://blog.csdn.net/abandonship/article/details/6459104 其中方法三的js代码在tp框架使用存在故障,一个是需要把代码写在一起(可能也不需 ...

  9. iOS-H5交互综合整理

    1.WKWebView的使用 2.常见问题 2.1 iOS开发 WKWebView下js的alert(),confirm(),prompt()方法无法正常执行

  10. 微信小程序实现下拉刷新上拉加载

    代码片段:https://developers.weixin.qq.com/s/K9VbWZmy7e8C