BZOJ 2333: [SCOI2011]棘手的操作
真的是个很棘手的操作。。
注意每删除一个点,就需要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]棘手的操作的更多相关文章
- BZOJ 2333: [SCOI2011]棘手的操作 可并堆 左偏树 set
https://www.lydsy.com/JudgeOnline/problem.php?id=2333 需要两个结构分别维护每个连通块的最大值和所有连通块最大值中的最大值,可以用两个可并堆实现,也 ...
- BZOJ 2333 SCOI2011 棘手的操作 并查集+可并堆
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2333 ..题意概述就不写了,各位老爷如果是看着玩的可以去搜一下,如果是做题找来的也知道题干 ...
- bzoj 2333 [SCOI2011]棘手的操作 —— 可并堆
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2333 稍微复杂,参考了博客:http://hzwer.com/5780.html 用 set ...
- BZOJ 2333 [SCOI2011]棘手的操作 (可并堆)
码农题.. 很显然除了两个全局操作都能用可并堆完成 全局最大值用个multiset记录,每次合并时搞一搞就行了 注意使用multiset删除元素时 如果直接delete一个值,会把和这个值相同的所有元 ...
- 2333: [SCOI2011]棘手的操作[写不出来]
2333: [SCOI2011]棘手的操作 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1979 Solved: 772[Submit][Stat ...
- 2333: [SCOI2011]棘手的操作[离线线段树]
2333: [SCOI2011]棘手的操作 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2325 Solved: 909[Submit][Stat ...
- 2333: [SCOI2011]棘手的操作[我不玩了]
2333: [SCOI2011]棘手的操作 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1979 Solved: 772[Submit][Stat ...
- 【BZOJ】2333: [SCOI2011]棘手的操作
http://www.lydsy.com/JudgeOnline/problem.php?id=2333 题意: 有N个节点,标号从1到N,这N个节点一开始相互不连通.第i个节点的初始权值为a[i], ...
- 【BZOJ 2333 】[SCOI2011]棘手的操作(离线+线段树)
2333: [SCOI2011]棘手的操作 Description 有N个节点,标号从1到N,这N个节点一开始相互不连通.第i个节点的初始权值为a[i],接下来有如下一些操作: U x y: 加一条边 ...
随机推荐
- docker相关--开始使用swarm模式
Swarm简介 Swarm是Docker的一个编排工具,参考官网:https://docs.docker.com/engine/swarm/ Swarm 模式简介 要在Swarm模式下运行docker ...
- CSS 实现盒子水平居中、垂直居中和水平垂直居中的方法
CSS 实现盒子模型水平居中 水平居中效果图如下: HTML: CSS 全局样式: 方法一:使用margin: 0 auto;(只适用于子盒子有宽的时候) 方法二:text-align + disp ...
- 将H5页面打包成安卓原生app
第一步:下载HBuilderX,新建项目选择5+App新建一个空项目如下图 新建后项目目录结构如下图 第二步,将你要打包成安卓app的文件打包,最后生成的文件目录如下图 1.打包完成后,将对应文件内容 ...
- React Native 开发豆瓣评分(六)添加字体图标
添加依赖 yarn add react-native-vector-icons Link 依赖 react-native link react-native-vector-icons 使用默认字体图标 ...
- JDK的安装(mac)
1.第一步安装brew 教学网址 2.用brew安装jdk. brew update brew cask install java(未翻墙时长很长,大概猴年马月两个小时) 安装完成后就可以执行JAVA ...
- java23种设计模式专攻:生产者-消费者模式的三种实现方式
公司的架构用到了dubbo.带我那小哥也是个半吊子,顺便就考我生产者消费者模式,顺便还考我23种java设计模式,
- 在Linux主机使用命令行批量删除harbor镜像
在Linux主机使用命令行批量删除harbor镜像 脚本使用说明: 此脚本不是万能脚本,根据自身环境要调整很多 能用harbor的域名就不要用IP 脚本前半部分可以套用,后半部分需一步一步试错,结合 ...
- python之while循环用法举例,break与continue的区别,格式化输出及运算符
一.while循环的基本结构 while 条件: 代码块(循环体) else: 当上面的条件为假. 才会执行 执行顺序:判断条件是否为真. 如果真. 执行循环体. 然后再次判断条件....直到循环条件 ...
- MySQL学习之基础篇09-事务
我们在建表的时候通常会在最后声明引擎类型,这次我们就来看看存储引擎都有哪些: 举个例子: --------------------------- 银行转账: 张三想给李四转500元钱: 张三-500 ...
- Python_变量作用域
1.变量作用域: def get_apple(name,*b): global totalCount totalCount=0 for num in b: print('............... ...