当前位置: 首页 > news >正文

【bzoj2333】 SCOI2011—棘手的操作

http://www.lydsy.com/JudgeOnline/problem.php?id=2333 (题目链接)

题意

  N个节点维护一些操作。。

Solution

  我们用可并大根堆进行维护。

  对于每个连通块建一个局部可并堆,因为要询问全局最大值,所以还要对全局建一个全局可并堆记录之前局部可并堆堆顶元素。

  U:合并x所在的堆以及y所在的堆,并在全局堆中删除合并前的局部堆堆顶元素,因为它合并以后已经不是其连通块的堆顶了。

  A1:在堆中删除,更新后再加入堆

  A2:找到其堆顶,对堆顶进行修改并打上标记

  A3:对全局都打个标记即可

  F1:将标记下传后输出

  F2:找到其所在的堆顶输出

  F3:输出全局堆的堆顶

  

  UPD:这个做法被×了,暴力找堆顶复杂度不对,得写启发式合并或者线段树,右转LCF。。当然拿来练练手也是可以的,反正能过数据

细节

  码农题就是细节多

代码

// bzoj2333
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
#define LL long long
#define inf 1<<30
#define Pi acos(-1.0)
#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
using namespace std;

const int maxn=300010;
struct heap {int val,tag,l,r,fa;}q[maxn],qq[maxn];
int n,m,rt,Tag;
char op[10];

void pushdown(heap *q,int k) {   //标记下传
	q[q[k].l].val+=q[k].tag;q[q[k].l].tag+=q[k].tag;
	q[q[k].r].val+=q[k].tag;q[q[k].r].tag+=q[k].tag;
	q[k].tag=0;
}
int merge(heap *q,int x,int y) {   //合并
	if (x==0 || y==0) return x+y;
	if (q[x].val<q[y].val) swap(x,y);
	if (q[x].tag) pushdown(q,x);
	q[x].r=merge(q,q[x].r,y);
	q[q[x].r].fa=x;
	swap(q[x].l,q[x].r);
	return x;
}
int find(heap *q,int x) {   //寻找堆顶并下传标记,注意下传标记和向上查询的顺序
	int tmp=x;
	if (q[x].fa) tmp=find(q,q[x].fa);
	if (q[x].tag) pushdown(q,x);
	return tmp;
}
int del(heap *q,int x) {   //删除
	int f=find(q,x);
	int tmp=merge(q,q[x].l,q[x].r);
	if (q[q[x].fa].l==x) q[q[x].fa].l=tmp;
	else q[q[x].fa].r=tmp;
	q[tmp].fa=q[x].fa;
	return f==x ? (tmp ? find(q,tmp) : 0) : f;   //返回删除后该堆的堆顶,此处不是很好处理,最好画个图理解一下
}
int build() {   //对全局建堆
	queue<int> Q;
	for (int i=1;i<=n;i++) Q.push(i),qq[i]=q[i];
	while (Q.size()>1) {
		int x=Q.front();Q.pop();
		int y=Q.front();Q.pop();
		Q.push(merge(qq,x,y));
	}
	return Q.front();
}
void newq(heap *q,int x,int val) {   //新建元素
	q[x].l=q[x].r=q[x].fa=0;
	q[x].val=val;
}
int main() {
	scanf("%d",&n);q[0].val=-inf;
	for (int i=1;i<=n;i++) scanf("%d",&q[i].val);
	rt=build();
	scanf("%d",&m);
	for (int x,y,i=1;i<=m;i++) {
		scanf("%s",op);
		if (op[0]=='U') {
			scanf("%d%d",&x,&y);
			int r1=find(q,x),r2=find(q,y);
			if (r1!=r2) {
				if (merge(q,r1,r2)==r1) rt=del(qq,r2);
				else rt=del(qq,r1);
			}
		}
		if (op[0]=='A') {
			if (op[1]=='1') {
				scanf("%d%d",&x,&y);
				rt=del(qq,find(q,x));
				int k=del(q,x);
				newq(q,x,q[x].val+y);
				k=merge(q,k,x);
				newq(qq,k,q[k].val);
				rt=merge(qq,k,rt);
			}
			if (op[1]=='2') {
				scanf("%d%d",&x,&y);
				int f=find(q,x);
				q[f].val+=y;q[f].tag+=y;
				rt=del(qq,f);
				newq(qq,f,qq[f].val+y);
				rt=merge(qq,rt,f);
			}
			if (op[1]=='3') scanf("%d",&y),Tag+=y;
		}
		if (op[0]=='F') {
			if (op[1]=='1') {
				scanf("%d",&x);
				find(q,x),printf("%d\n",q[x].val+Tag);
			}
			if (op[1]=='2') {
				scanf("%d",&x);
				printf("%d\n",q[find(q,x)].val+Tag);
			}
			if (op[1]=='3') printf("%d\n",qq[rt].val+Tag);
		}
	}
    return 0;
}

 

转载于:https://www.cnblogs.com/MashiroSky/p/6266559.html

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • java各数据类型之间的转换
  • Android笔记(三):View一些值得注意的地方
  • java常用正则表达式
  • Ubuntu 检测到系统出现问题 弹窗 嘿嘿
  • 日期年月日正则表达式
  • 最近一周的日期选择设置
  • hibernate增加,删除,修改,查找操作
  • javaWEB总结(17):cookie概述
  • flex获得当前player版本信息
  • Struts入门(二) 配置文件的讲解
  • flex rpc 错误整理
  • 提高网页关键词排名的实用方法
  • 疯狂Java讲义(十一)---- 初始化块
  • java.lang.ClassNotFoundException: com.microsoft.jdbc.sqlserver.SQLServerDriver
  • javaweb学习总结(三十六)——使用JDBC进行批处理
  • 【140天】尚学堂高淇Java300集视频精华笔记(86-87)
  • 【node学习】协程
  • 【刷算法】从上往下打印二叉树
  • ECMAScript6(0):ES6简明参考手册
  • Flannel解读
  • HTTP传输编码增加了传输量,只为解决这一个问题 | 实用 HTTP
  • IE报vuex requires a Promise polyfill in this browser问题解决
  • Java 多线程编程之:notify 和 wait 用法
  • java小心机(3)| 浅析finalize()
  • React-Native - 收藏集 - 掘金
  • Sequelize 中文文档 v4 - Getting started - 入门
  • XForms - 更强大的Form
  • 阿里云爬虫风险管理产品商业化,为云端流量保驾护航
  • 从输入URL到页面加载发生了什么
  • 构造函数(constructor)与原型链(prototype)关系
  • 坑!为什么View.startAnimation不起作用?
  • 排序(1):冒泡排序
  • 如何将自己的网站分享到QQ空间,微信,微博等等
  • raise 与 raise ... from 的区别
  • ​一文看懂数据清洗:缺失值、异常值和重复值的处理
  • ## 1.3.Git命令
  • #Spring-boot高级
  • (2)nginx 安装、启停
  • (2020)Java后端开发----(面试题和笔试题)
  • (7)STL算法之交换赋值
  • (day18) leetcode 204.计数质数
  • (附源码)springboot课程在线考试系统 毕业设计 655127
  • (接上一篇)前端弄一个变量实现点击次数在前端页面实时更新
  • (七)Flink Watermark
  • (转)Mysql的优化设置
  • (转)人的集合论——移山之道
  • (自适应手机端)响应式新闻博客知识类pbootcms网站模板 自媒体运营博客网站源码下载
  • .cfg\.dat\.mak(持续补充)
  • .NET C# 使用 iText 生成PDF
  • .NET MVC 验证码
  • .net 获取url的方法
  • .net 写了一个支持重试、熔断和超时策略的 HttpClient 实例池
  • .NET开源纪元:穿越封闭的迷雾,拥抱开放的星辰
  • @JoinTable会自动删除关联表的数据
  • @拔赤:Web前端开发十日谈