真--可并堆模板--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 读入所有数据,先模拟一遍所有的合并操作 我们不关心联通块长什么样,只关心联通块内有谁 所以可以 ...
随机推荐
- laravel 学习
解决办法:没有开启PHP.ini的fileinfo扩展
- C# Equals的重写
using System; using System.Collections.Generic; using System.Text; namespace Equal { using Syste ...
- 解决ASP.NET Core通过docker-compose up启动应用无法配置https的解决办法
错误重现一下: 新建了一个ASP.NET Core应用,在VS2017下添加Docker支持,选择Linux环境 然后再给这个web应用再右键添加容器业务流程协调程序支持,然后解决方案就多了一个doc ...
- sh/bash/csh/Tcsh/ksh/pdksh等shell本质区别
sh/bash/csh/Tcsh/ksh/pdksh等shell本质区别 1. Shell脚本的书写 在写Shell脚本时,往往第一行要注明用什么解释器来解释这个脚本. 如#!/bin/bash即用/ ...
- 利用Wamp在本地搭建一个wordpress站点
原文链接:利用Wamp在本地搭建一个wordpress站点 有时候我们会想搭建一个自己的站点,可是由于只是想自己访问,就不是很想为这个站点在买一个服务器和域名,那我们可能首先就想到把自己电脑当做服务器 ...
- iOS Programming NSUserDefaults
iOS Programming NSUserDefaults When you start an app for the first time, it uses its factory settin ...
- jQuery.ajax() 设置 Headers 中的 Accept 内容
jQuery.ajax() 如何设置 Headers 中的 Accept 内容 其实很简单,首先如果是常见类型,则请直接设置 dataType 属性 $.ajax({ dataType: &quo ...
- 慎将MBTI测试用于招聘或就业:4星|《人格魅力修炼指南》
人格魅力修炼指南:成为理想中的自己,就靠它了!(<哈佛商业评论>增刊) <哈佛商业评论>的11篇领导者人格魅力相关的文章.比较专业. 一些重要的信息:慎将MBTI测试用于“招聘 ...
- arcpy利用XY创建点
# -*- coding: utf-8 -*-"""Created on Sun Apr 7 15:32:24 2019@author: ""&quo ...
- hdfs的特性、命令、安全模式、基准测试
1.第一点:如何理解hdfs分布式文件系统,每台机器出一块磁盘,凑成一个大的硬盘,大的硬盘的容量来自各个服务器的硬盘容量之和. 你出5毛,我出5毛,大家凑成1块. 2. HDFS 是 Hadoop D ...