真--可并堆模板--BZOJ2333: [SCOI2011]棘手的操作
n<=300000个点,开始是独立的,m<=300000个操作:

方法一:单点修改、查询,区间修改、查询?等等等等这里修改是块修改不是连续的啊,那就让他连续呗!具体方法:离线后,每次连接两棵树u,v时,把v放到u树根节点的最后,使其dfs序最后,最后扫一次把每棵树dfs一下搞出这个序列,然后线段树操作即可。
怎么把v放到u的儿子最后???强制一下连边顺序!!根据你写的邻接表,决定过程中的边是要正连还是倒连以达到目标顺序。有点抽象,见代码。
没写。
方法二:真正“棘手的操作”--可并堆!!!
如果是散散的点再连起来,可并堆的期望深度是小小的,可以做标记下传的!!
大体的思路是,每个块一个堆,然后每个堆的根节点的值再搞一个堆,就可以回答所有询问。然后来看看怎么操作:
U:直接合并。
A1:单点加,那就相当于单点查,单点删,单点加。单点删和单点加详见
单点查的话就标记下传就行了。。
A2:块加,打标记。
A3:是来搞笑的吗,记个全局变量。
F1:单点查,同上。
F2,F3:来搞笑的。
总之,重点在于:两个堆同时操作。
这次复合数据结构题的整体构思比以前有进步,但!!可并堆和并查集的结合非常混乱,这题要再写。
#include<string.h>
#include<stdlib.h>
#include<stdio.h>
#include<math.h>
//#include<assert.h>
#include<algorithm>
//#include<iostream>
using namespace std; int n,m;
#define maxn 300011
struct leftist
{
struct Node
{
int fa,ls,rs,v,dis,add;
}a[maxn];
leftist() {a[].dis=-;}
void addsingle(int x,int v)
{
if (!x) return;
(a[x].v+=v);
a[x].add+=v;
}
void down(int x)
{
int &p=a[x].ls,&q=a[x].rs;
if (a[x].add) {addsingle(p,a[x].add); addsingle(q,a[x].add); a[x].add=;}
}
int sta[maxn];
void download(int x)
{
int top=;
for (int i=x;i;i=a[i].fa) sta[++top]=i;
for (;top;top--) down(sta[top]);
}
int merge(int x,int y)
{
if (!x || !y) return x^y;
if (a[x].v<a[y].v) {int t=x; x=y; y=t;}
down(x);
a[x].rs=merge(a[x].rs,y);
if (a[a[x].ls].dis<a[a[x].rs].dis) {int t=a[x].ls; a[x].ls=a[x].rs; a[x].rs=t;}
a[x].dis=a[a[x].rs].dis+;
if (a[x].rs) a[a[x].rs].fa=x; if (a[x].ls) a[a[x].ls].fa=x;
return x;
}
void Delete(int &root,int x)
{
int y=a[x].fa,w=(x==a[y].rs); x=merge(a[x].ls,a[x].rs); a[x].fa=y;
if (!y) {root=x; return;}
if (w) a[y].rs=x; else a[y].ls=x;
if (a[a[y].ls].dis<a[a[y].rs].dis) {int t=a[y].ls; a[y].ls=a[y].rs; a[y].rs=t;}
x=a[y].rs;
while (y && a[y].dis!=a[x].dis+)
{
a[y].dis=a[x].dis+;
x=y; y=a[y].fa;
if (a[a[y].ls].dis<a[a[y].rs].dis) {int t=a[y].ls; a[y].ls=a[y].rs; a[y].rs=t;}
x=a[y].rs;
}
}
void push(int id,int &root,int val)
{
a[id].fa=a[id].ls=a[id].rs=a[id].dis=a[id].add=; a[id].v=val;
root=merge(root,id);
}
int top(int root) {return a[root].v;}
}q,qtot;
int root[maxn];
int find(int x) {return x==root[x]?x:(root[x]=find(root[x]));} int main()
{
scanf("%d",&n);
for (int i=,x;i<=n;i++) scanf("%d",&x),q.push(i,root[i],x),qtot.push(i,root[],x);
scanf("%d",&m);
char c;int x,y; int totadd=;
for (int i=;i<=m;i++)
{
while ((c=getchar())!='U' && c!='A' && c!='F');
if (c=='U')
{
scanf("%d%d",&x,&y); x=find(x); y=find(y);
if (x==y) continue;
qtot.Delete(root[],y); qtot.Delete(root[],x);
root[x]=root[y]=q.merge(x,y);
x=root[x]; qtot.push(x,root[],q.a[x].v);
}
else if (c=='A')
{
c=getchar();
if (c=='')
{
scanf("%d%d",&x,&y); find(x);
qtot.Delete(root[],root[x]);
q.download(x); int tmp=q.a[x].v;
q.Delete(root[x],x); int z=root[x];
if (z) root[z]=z,q.push(x,root[z],tmp+y),root[x]=root[z];
else q.push(x,root[x],tmp+y);
qtot.push(root[x],root[],q.a[root[x]].v);
}
else if (c=='')
{
scanf("%d%d",&x,&y); x=find(x); qtot.Delete(root[],x);
q.addsingle(x,y); qtot.push(x,root[],q.a[x].v);
}
else if (c=='')
{
scanf("%d",&x);
totadd+=x;
}
}
else
{
c=getchar();
if (c=='')
{
scanf("%d",&x);
q.download(x);
printf("%d\n",q.a[x].v+totadd);
}
else if (c=='')
{
scanf("%d",&x); x=find(x);
printf("%d\n",q.a[x].v+totadd);
}
else printf("%d\n",qtot.a[root[]].v+totadd);
}
}
return ;
}
真--可并堆模板--BZOJ2333: [SCOI2011]棘手的操作的更多相关文章
- [bzoj2333] [SCOI2011]棘手的操作 (可并堆)
//以后为了凑字数还是把题面搬上来吧2333 发布时间果然各种应景... Time Limit: 10 Sec Memory Limit: 128 MB Description 有N个节点,标号从1 ...
- BZOJ2333 [SCOI2011]棘手的操作 堆 左偏树 可并堆
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ2333 题意概括 有N个节点,标号从1到N,这N个节点一开始相互不连通.第i个节点的初始权值为a[i ...
- (右偏树)Bzoj2333: [SCOI2011]棘手的操作
题面 戳我 Sol 右偏树滑稽+并查集 再在全局开一个可删除的堆(priority_queue) 注意细节 # include <bits/stdc++.h> # define RG re ...
- 2019.01.17 bzoj2333: [SCOI2011]棘手的操作(启发式合并)
传送门 启发式合并菜题. 题意:支持与连通块有关的几种操作. 要求支持连边,单点修改,连通块修改,全局修改和单点查值,连通块查最大值和全局最大值. 我们对每个连通块和答案用可删堆维护最大值,然后用启发 ...
- BZOJ2333:[SCOI2011]棘手的操作(Splay)
Description 有N个节点,标号从1到N,这N个节点一开始相互不连通.第i个节点的初始权值为a[i],接下来有如下一些操作: U x y: 加一条边,连接第x个节点和第y个节点 A1 x v: ...
- BZOJ2333 [SCOI2011]棘手的操作 【离线 + 线段树】
题目 有N个节点,标号从1到N,这N个节点一开始相互不连通.第i个节点的初始权值为a[i],接下来有如下一些操作: U x y: 加一条边,连接第x个节点和第y个节点 A1 x v: 将第x个节点的权 ...
- bzoj2333[SCOI2011]棘手的操作 洛谷P3273 [SCOI2011]棘手的操作
2333? 先记一下吧,这题现在全部都是照着题解做的,因为怎么改都改不出来,只好对着题解改,以后还要再做过 以后再也不用指针了!太恶心了!空指针可不止直接特判那么简单啊,竟然还要因为空指针写奇怪的分类 ...
- bzoj2333 [SCOI2011]棘手的操作
用set维护每个联通块里的最值,multiset维护所有块里的最值,并查集维护连通性,然后随便搞搞就行了,合并时候采用启发式合并.复杂度O(nlognlogn),大概勉强过的程度,反正跑的很慢就是了. ...
- bzoj千题计划217:bzoj2333: [SCOI2011]棘手的操作
http://www.lydsy.com/JudgeOnline/problem.php?id=2333 读入所有数据,先模拟一遍所有的合并操作 我们不关心联通块长什么样,只关心联通块内有谁 所以可以 ...
随机推荐
- jmeter(一)工具介绍(二)
1.Jmeter 概要描叙 jmeter 是一款专门用于功能测试和压力测试的轻量级测试开发平台.多数情况下是用作压力测试,该测试工具在阿里巴巴有着广泛的使用,估计是不要钱吧,哈哈,功能上来说,整个平台 ...
- 设计模式 -- Abstract Factory 抽象工厂
1.常规的对象创建方法 //创建一个Road对象 Road road=new Road(); new的问题:实现依赖,不能应对“具体实例化类型”额变化. 解决思想: 封装变化点--哪里变化,封装哪里( ...
- 用nowrap实现div内的元素不换行
在编写自定义插件my-slider的过程中,发现无论float还是inline-block均不能保证div内的内容不换行(这两个属性在内容超出容器尺寸后,均将剩余内容做换行处理),在浏览器内比较了自己 ...
- object -c OOP , 源码组织 ,Foundation 框架 详解1
object -c OOP , 源码组织 ,Foundation 框架 详解1 1.1 So what is OOP? OOP is a way of constructing softwar ...
- linux下php访问sql server设置
安装freeIDS 官网下载地址: wget ftp://ftp.freetds.org/pub/freetds/stable/freetds-1.00.18.tar.gz 1.1.到下载目录解压 t ...
- KMP中next数组的理解与应用
理解 1.next数组一直往前走 next数组一直往前走,得到的所有前缀也是当前主串的后缀,当然了,也是当前主串的前缀. 2.周期性字符串 1.周期性字符串$\Leftrightarrow n \,\ ...
- 关于 <script type='text/template' > 的妙用 / 使用jquery获取iframe加载完成事件
https://www.cnblogs.com/ddqyc/p/6200539.html <!DOCTYPE html> <html> <head> <met ...
- Learning Discriminative and Transformation Covariant Local Feature Detectors实验环境搭建详细过程
依赖项: Python 3.4.3 tensorflow>1.0.0, tqdm, cv2, exifread, skimage, glob 1.安装tensorflow:https://www ...
- mybatis generator 覆盖xml文件
mybatis generator默认采用追加方式生成,所以我们如果要重新生成代码的时候那么要先删除原来的文件. 解决办法: 1:创建一个自定义补丁类. OverwriteXmlPlugin.java ...
- SVN CommandLine
要是SVN命令行用不了的话: 1.SVN装了没? 2.SVN安装时,选项“command line client tools”选了没. 检出: svn checkout [-depth ARG] [- ...