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]棘手的操作的更多相关文章

  1. [bzoj2333] [SCOI2011]棘手的操作 (可并堆)

    //以后为了凑字数还是把题面搬上来吧2333 发布时间果然各种应景... Time Limit: 10 Sec  Memory Limit: 128 MB Description 有N个节点,标号从1 ...

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

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

  3. (右偏树)Bzoj2333: [SCOI2011]棘手的操作

    题面 戳我 Sol 右偏树滑稽+并查集 再在全局开一个可删除的堆(priority_queue) 注意细节 # include <bits/stdc++.h> # define RG re ...

  4. 2019.01.17 bzoj2333: [SCOI2011]棘手的操作(启发式合并)

    传送门 启发式合并菜题. 题意:支持与连通块有关的几种操作. 要求支持连边,单点修改,连通块修改,全局修改和单点查值,连通块查最大值和全局最大值. 我们对每个连通块和答案用可删堆维护最大值,然后用启发 ...

  5. BZOJ2333:[SCOI2011]棘手的操作(Splay)

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

  6. BZOJ2333 [SCOI2011]棘手的操作 【离线 + 线段树】

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

  7. bzoj2333[SCOI2011]棘手的操作 洛谷P3273 [SCOI2011]棘手的操作

    2333? 先记一下吧,这题现在全部都是照着题解做的,因为怎么改都改不出来,只好对着题解改,以后还要再做过 以后再也不用指针了!太恶心了!空指针可不止直接特判那么简单啊,竟然还要因为空指针写奇怪的分类 ...

  8. bzoj2333 [SCOI2011]棘手的操作

    用set维护每个联通块里的最值,multiset维护所有块里的最值,并查集维护连通性,然后随便搞搞就行了,合并时候采用启发式合并.复杂度O(nlognlogn),大概勉强过的程度,反正跑的很慢就是了. ...

  9. bzoj千题计划217:bzoj2333: [SCOI2011]棘手的操作

    http://www.lydsy.com/JudgeOnline/problem.php?id=2333 读入所有数据,先模拟一遍所有的合并操作 我们不关心联通块长什么样,只关心联通块内有谁 所以可以 ...

随机推荐

  1. laravel 学习

    解决办法:没有开启PHP.ini的fileinfo扩展

  2. C# Equals的重写

    using System; using System.Collections.Generic; using System.Text; namespace Equal {     using Syste ...

  3. 解决ASP.NET Core通过docker-compose up启动应用无法配置https的解决办法

    错误重现一下: 新建了一个ASP.NET Core应用,在VS2017下添加Docker支持,选择Linux环境 然后再给这个web应用再右键添加容器业务流程协调程序支持,然后解决方案就多了一个doc ...

  4. sh/bash/csh/Tcsh/ksh/pdksh等shell本质区别

    sh/bash/csh/Tcsh/ksh/pdksh等shell本质区别 1. Shell脚本的书写 在写Shell脚本时,往往第一行要注明用什么解释器来解释这个脚本. 如#!/bin/bash即用/ ...

  5. 利用Wamp在本地搭建一个wordpress站点

    原文链接:利用Wamp在本地搭建一个wordpress站点 有时候我们会想搭建一个自己的站点,可是由于只是想自己访问,就不是很想为这个站点在买一个服务器和域名,那我们可能首先就想到把自己电脑当做服务器 ...

  6. iOS Programming NSUserDefaults

    iOS Programming NSUserDefaults  When you start an app for the first time, it uses its factory settin ...

  7. jQuery.ajax() 设置 Headers 中的 Accept 内容

    jQuery.ajax() 如何设置 Headers 中的 Accept 内容   其实很简单,首先如果是常见类型,则请直接设置 dataType 属性 $.ajax({ dataType: &quo ...

  8. 慎将MBTI测试用于招聘或就业:4星|《人格魅力修炼指南》

    人格魅力修炼指南:成为理想中的自己,就靠它了!(<哈佛商业评论>增刊) <哈佛商业评论>的11篇领导者人格魅力相关的文章.比较专业. 一些重要的信息:慎将MBTI测试用于“招聘 ...

  9. arcpy利用XY创建点

    # -*- coding: utf-8 -*-"""Created on Sun Apr 7 15:32:24 2019@author: ""&quo ...

  10. hdfs的特性、命令、安全模式、基准测试

    1.第一点:如何理解hdfs分布式文件系统,每台机器出一块磁盘,凑成一个大的硬盘,大的硬盘的容量来自各个服务器的硬盘容量之和. 你出5毛,我出5毛,大家凑成1块. 2. HDFS 是 Hadoop D ...