【BZOJ2333】棘手的操作(左偏树,STL)

题面

BZOJ上看把。。。

题解

正如这题的题号

我只能\(2333\)

神TM棘手的题目。。。

前面的单点/联通块操作

很显然是一个左偏树+标记

(确实很显然,只是写死人。。。)

然后对于全局的最大值而言

搞一个\(multi\)来水

看起来真的简单。。

写起来真的想死。。。

记住:要特判一下已经联通的块就不要再去\(Merge\)了

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define MAX 300010
inline int read()
{
int x=0,t=1;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=-1,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return x*t;
}
int n;
multiset<int> S;
struct Node
{
int ls,rs,ff;
int v,dis;
int lz;
}t[MAX];
int Lazy,root;
int getf(int x){while(t[x].ff)x=t[x].ff;return x;}
void putlazy(int x,int w)
{
t[x].v+=w;
t[x].lz+=w;
}
void pushdown(int x)
{
if(!t[x].lz)return;
if(t[x].ls)putlazy(t[x].ls,t[x].lz);
if(t[x].rs)putlazy(t[x].rs,t[x].lz);
t[x].lz=0;
}
int Merge(int r1,int r2)
{
if(!r1||!r2)return r1+r2;
pushdown(r1);pushdown(r2);
if(t[r1].v<t[r2].v)swap(r1,r2);
t[r1].rs=Merge(t[r1].rs,r2);
t[t[r1].rs].ff=r1;
if(t[t[r1].ls].dis<t[t[r1].rs].dis)swap(t[r1].ls,t[r1].rs);
t[r1].dis=t[t[r1].rs].dis+1;
return r1;
}
void Update(int x)
{
if(!x)return;
if(t[t[x].ls].dis<t[t[x].rs].dis)swap(t[x].ls,t[x].rs);
t[x].dis=t[t[x].rs].dis+1;
Update(t[x].ff);
}
void Alldown(int x)
{
if(t[x].ff)Alldown(t[x].ff);
pushdown(x);
}
void Del(int x)
{
Alldown(x);
t[t[x].ls].ff=t[t[x].rs].ff=0;
if(t[t[x].ff].rs==x)t[t[x].ff].rs=0;
else t[t[x].ff].ls=0;
int rtt=getf(t[x].ff);
Merge(rtt,Merge(t[x].ls,t[x].rs));
Update(t[x].ff);
t[x].ff=t[x].ls=t[x].rs=0;
}
void Plus(int x,int w)//单点修改
{
int rtt=getf(x);
if(!t[x].ff)
{
S.erase(S.find(t[x].v));
t[t[x].ls].ff=t[t[x].rs].ff=0;
pushdown(x),rtt=Merge(t[x].ls,t[x].rs);
t[x].ff=t[x].ls=t[x].rs=0;
}
else Del(x),S.erase(S.find(t[rtt].v));
t[x].v+=w;
int gg=Merge(x,rtt);
S.insert(t[gg].v);
}
void AllPlus(int x,int w)
{
x=getf(x);
S.erase(S.find(t[x].v));
putlazy(x,w);
S.insert(t[x].v);
}
int main()
{
n=read();
for(int i=1;i<=n;++i)t[i].v=read(),S.insert(t[i].v);
int Q=read();
char ch[5];
while(Q--)
{
scanf("%s",ch);
if(ch[0]=='A')
{
if(ch[1]=='1')
{
int x=read(),v=read();
Plus(x,v);
}
else if(ch[1]=='2')
{
int x=read(),v=read();
AllPlus(x,v);
}
else Lazy+=read();
}
else if(ch[0]=='F')
{
if(ch[1]=='1')
{
int x=read();
Alldown(x);
printf("%d\n",t[x].v+Lazy);
}
else if(ch[1]=='2')
{
int x=read();
x=getf(x);
printf("%d\n",t[x].v+Lazy);
}
else printf("%d\n",*--S.end()+Lazy);
}
else
{
int x=read(),y=read();
x=getf(x),y=getf(y);
if(x==y)continue;
int kk=Merge(x,y);
S.erase(S.find(kk==x?t[y].v:t[x].v));
}
}
return 0;
}

【BZOJ2333】棘手的操作(左偏树,STL)的更多相关文章

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

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

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

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

  3. 左偏树 / 非旋转treap学习笔记

    背景 非旋转treap真的好久没有用过了... 左偏树由于之前学的时候没有写学习笔记, 学得也并不牢固. 所以打算写这么一篇学习笔记, 讲讲左偏树和非旋转treap. 左偏树 定义 左偏树(Lefti ...

  4. BZOJ2333 [SCOI2011]棘手的操作 堆 左偏树 可并堆

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ2333 题意概括 有N个节点,标号从1到N,这N个节点一开始相互不连通.第i个节点的初始权值为a[i ...

  5. 【BZOJ 2333 】[SCOI2011]棘手的操作(离线+线段树|可并堆-左偏树)

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

  6. P3378 【模板】堆 (内含左偏树实现)

    P3378 [模板]堆 题解 其实就是一个小根堆啦,STL就可以解决,但是拥有闲情雅致的我学习了Jelly_Goat的左偏树,增加了代码长度,妙啊 Solution 1 STL STL 里面prior ...

  7. 洛谷P3377 【模板】左偏树(可并堆) 题解

    作者:zifeiy 标签:左偏树 这篇随笔需要你在之前掌握 堆 和 二叉树 的相关知识点. 堆支持在 \(O(\log n)\) 的时间内进行插入元素.查询最值和删除最值的操作.在这里,如果最值是最小 ...

  8. 【bzoj2809】[Apio2012]dispatching 左偏树

    2016-05-31  15:56:57 题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2809 直观的思想是当领导力确定时,尽量选择薪水少的- ...

  9. 左偏树(Leftist Heap/Tree)简介及代码

    左偏树是一种常用的优先队列(堆)结构.与二叉堆相比,左偏树可以高效的实现两个堆的合并操作. 左偏树实现方便,编程复杂度低,而且有着不俗的效率表现. 它的一个常见应用就是与并查集结合使用.利用并查集确定 ...

随机推荐

  1. qt窗口的切换

    思想:在一个窗口类中声明另一继承与Qdialog的类的变量 还有在另一类中parentwidget()函数获取父类窗口,然后将其隐藏.. 窗口1: mywin1.h #ifndef MYWIN1_H ...

  2. 使用Spring Boot搭建应用开发框架(一) —— 基础架构

    Spring的简史 第一阶段:XML配置,在Spring1.x时代,使用Spring开发满眼都是xml配置的Bean,随着项目的扩大,我们需要把xml配置文件分放到不同的配置文件里,那时候需要频繁的在 ...

  3. mysql 密码过期问题

    问题描述: Your password has expired. To log in you must change it using a client that supports expired p ...

  4. MathJax使用指南

    MathJax使用指南 SublimePrettyJson Github CSDN-Markdown语法集锦 LaTex 简明教程 在Markdown中输入数学公式(MathJax) MathJax ...

  5. Rsync(远程同步): linux中Rsync命令的实际示例

    rsync的 ( 远程同步 )为在Linux / Unix系统局部 拷贝和同步文件和目录远程以及一个最常用的命令. 随着rsync命令的帮助,您可以复制并在目录中远程和本地同步数据,在磁盘和网络,进行 ...

  6. H5 拖拽,一个函数搞定,直接指定对象设置可拖拽

    页面上,弹个小窗体,想让它可以拖拽,又不想 加载一堆js,就简单的能让他可以拖动? 嗯,下面有这样一个函数,调用下就好了! 1. 先来说说 H5的 拖拽 在 HTML5 中,拖放是标准的一部分,任何元 ...

  7. Java集合中的AbstractMap抽象类

    jdk1.8.0_144 AbstractMap抽象类实现了一些简单且通用的方法,本身并不难.但在这个方法中有两个方法非常值得关注,keySet和values方法源码的实现可以说是教科书式的典范. 抽 ...

  8. 浅谈session,cookie,sessionStorage,localStorage的区别及应用场景

    浏览器的缓存机制提供了可以将用户数据存储在客户端上的方式,可以利用cookie,session等跟服务端进行数据交互. 一.cookie和session cookie和session都是用来跟踪浏览器 ...

  9. CentOS常用命令搜集

    centos是32或者64位:getconf LONG_BIT

  10. MySql全国省市区SQL语句

    CREATE TABLE IF NOT EXISTS `province` (   `id` int(11) NOT NULL auto_increment,   `provinceID` int(1 ...