【BZOJ2333】【SCOI2011】棘手的操作 treap合并
题目大意
有\(n\)个节点,标号从1到\(n\),这\(n\)个节点一开始相互不连通。第\(i\)个节点的初始权值为\(a_i\),接下来有如下一些操作:
\(U~x~y\):加一条边,连接第\(x\)个节点和第\(y\)个节点。
\(A1~x~v\):将第\(x\)个节点的权值增加\(v\)。
\(A2~x~v\):将第\(x\)个节点所在的连通块的所有节点的权值都增加\(v\)。
\(A3~v\):将所有节点的权值都增加\(v\)。
\(F1~x\):输出第\(x\)个节点当前的权值。
\(F2~x\):输出第\(x\)个节点所在的连通块中,权值最大的节点的权值。
\(F3\):输出所有节点中,权值最大的节点的权值。
\(n,m\leq 300000,-1000\leq v,a_i\leq 1000\)
题解
如果没有点修改就可以用可合并堆维护。但是现在有点修改,这样就需要遍历\(x\)到根。然而可合并堆的深度是\(O(n)\)的,这样做会直接TLE。
那么还有没有什么其他的数据结构能支持合并和修改权值呢?
答案是:有。可以用线段树或非旋treap。合并均摊是\(O(\log n)\)的。我选择了treap。
treap合并在我的博客的另外一篇里面有写。
再拿一棵树维护所有treap的最大值的最大值。
用一个数维护全部节点的权值同时加了多少。输出时把这个加到答案上面去就可以了。
时间复杂度:\(O((n+m)\log n)\)
UPD:直接用treap的merge就行了。
代码
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<ctime>
#include<utility>
#include<cmath>
#include<functional>
#include<set>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
void sort(int &a,int &b)
{
	if(a>b)
		swap(a,b);
}
void open(const char *s)
{
#ifndef ONLINE_JUDGE
	char str[100];
	sprintf(str,"%s.in",s);
	freopen(str,"r",stdin);
	sprintf(str,"%s.out",s);
	freopen(str,"w",stdout);
#endif
}
struct node
{
	int f,ls,rs;
	int k,v,t,s;
	int sz;
	int u;
};
node a[300010];
int cnt=0;
int newnode(int u,int v)
{
	int x=++cnt;
	a[x].u=u;
	a[x].v=a[x].s=v;
	a[x].sz=1;
	return x;
}
void add(int x,int v)
{
	a[x].v+=v;
	a[x].s+=v;
	a[x].t+=v;
}
void push(int x)
{
	if(a[x].t)
	{
		if(a[x].ls)
			add(a[x].ls,a[x].t);
		if(a[x].rs)
			add(a[x].rs,a[x].t);
		a[x].t=0;
	}
}
void mt(int x)
{
	a[x].s=a[x].v;
	if(a[x].ls)
		a[x].s=max(a[x].s,a[a[x].ls].s);
	if(a[x].rs)
		a[x].s=max(a[x].s,a[a[x].rs].s);
	a[x].sz=a[a[x].ls].sz+a[a[x].rs].sz+1;
}
void pushdown(int x)
{
	if(a[x].f)
		pushdown(a[x].f);
	push(x);
}
void pushup(int x)
{
	mt(x);
	if(a[x].f)
		pushup(a[x].f);
}
int merge(int x,int y)
{
	if(!x||!y)
		return x+y;
	if(a[x].k<a[y].k)
	{
		push(x);
		a[x].rs=merge(a[x].rs,y);
		mt(x);
		if(a[x].rs)
			a[a[x].rs].f=x;
		return x;
	}
	else
	{
		push(y);
		a[y].ls=merge(x,a[y].ls);
		mt(y);
		if(a[y].ls)
			a[a[y].ls].f=y;
		return y;
	}
}
pii split(int x,int v)
{
	if(!x)
		return pii();
	push(x);
	if(v<a[x].u)
	{
		pii s=split(a[x].ls,v);
		a[x].ls=s.second;
		if(s.second)
			a[s.second].f=x;
		s.second=x;
		a[x].f=0;
		return s;
	}
	else
	{
		pii s=split(a[x].rs,v);
		a[x].rs=s.first;
		if(s.first)
			a[s.first].f=x;
		s.first=x;
		a[x].f=0;
		return s;
	}
}
int join(int x,int y)
{
	if(!x||!y)
		return x+y;
	if(a[x].k>a[y].k)
		swap(x,y);
	push(x);
	pii s=split(y,a[x].v);
	a[x].ls=merge(a[x].ls,s.first);
	a[x].rs=merge(a[x].rs,s.second);
	if(a[x].ls)
		a[a[x].ls].f=x;
	if(a[x].rs)
		a[a[x].rs].f=x;
	mt(x);
	return x;
}
int f[300010];
int find(int x)
{
	return f[x]==x?x:f[x]=find(f[x]);
}
int rt[300010];
multiset<int> s;
int main()
{
	open("bzoj2333");
	int n;
	scanf("%d",&n);
	int i,x;
	for(i=1;i<=n;i++)
	{
		scanf("%d",&x);
		rt[i]=newnode(i,x);
		f[i]=i;
		s.insert(x);
	}
	char op[5];
	int y,v;
	int all=0;
	int m;
	int ans;
	scanf("%d",&m);
	for(i=1;i<=m;i++)
	{
		scanf("%s",op);
		if(op[0]=='U')
		{
			scanf("%d%d",&x,&y);
			x=find(x);
			y=find(y);
			if(x==y)
				continue;
			f[x]=y;
			s.erase(s.find(min(a[rt[x]].s,a[rt[y]].s)));
			rt[y]=join(rt[x],rt[y]);
		}
		else if(op[0]=='A'&&op[1]=='1')
		{
			scanf("%d%d",&x,&v);
			y=find(x);
			s.erase(s.find(a[rt[y]].s));
			pushdown(x);
			a[x].v+=v;
			pushup(x);
			s.insert(a[rt[y]].s);
		}
		else if(op[0]=='A'&&op[1]=='2')
		{
			scanf("%d%d",&x,&v);
			x=find(x);
			s.erase(s.find(a[rt[x]].s));
			add(rt[x],v);
			s.insert(a[rt[x]].s);
		}
		else if(op[0]=='A'&&op[1]=='3')
		{
			scanf("%d",&y);
			all+=y;
		}
		else if(op[1]=='1')
		{
			scanf("%d",&x);
			pushdown(x);
			ans=a[x].v+all;
			printf("%d\n",ans);
		}
		else if(op[1]=='2')
		{
			scanf("%d",&x);
			x=find(x);
			ans=a[rt[x]].s+all;
			printf("%d\n",ans);
		}
		else
		{
			ans=*s.rbegin()+all;
			printf("%d\n",ans);
		}
	}
	return 0;
}
【BZOJ2333】【SCOI2011】棘手的操作 treap合并的更多相关文章
- 真--可并堆模板--BZOJ2333: [SCOI2011]棘手的操作
		n<=300000个点,开始是独立的,m<=300000个操作: 方法一:单点修改.查询,区间修改.查询?等等等等这里修改是块修改不是连续的啊,那就让他连续呗!具体方法:离线后,每次连接两 ... 
- bzoj2333[SCOI2011]棘手的操作 洛谷P3273 [SCOI2011]棘手的操作
		2333? 先记一下吧,这题现在全部都是照着题解做的,因为怎么改都改不出来,只好对着题解改,以后还要再做过 以后再也不用指针了!太恶心了!空指针可不止直接特判那么简单啊,竟然还要因为空指针写奇怪的分类 ... 
- 2019.01.17 bzoj2333: [SCOI2011]棘手的操作(启发式合并)
		传送门 启发式合并菜题. 题意:支持与连通块有关的几种操作. 要求支持连边,单点修改,连通块修改,全局修改和单点查值,连通块查最大值和全局最大值. 我们对每个连通块和答案用可删堆维护最大值,然后用启发 ... 
- [bzoj2333] [SCOI2011]棘手的操作 (可并堆)
		//以后为了凑字数还是把题面搬上来吧2333 发布时间果然各种应景... Time Limit: 10 Sec Memory Limit: 128 MB Description 有N个节点,标号从1 ... 
- bzoj千题计划217:bzoj2333: [SCOI2011]棘手的操作
		http://www.lydsy.com/JudgeOnline/problem.php?id=2333 读入所有数据,先模拟一遍所有的合并操作 我们不关心联通块长什么样,只关心联通块内有谁 所以可以 ... 
- BZOJ2333 [SCOI2011]棘手的操作 堆 左偏树 可并堆
		欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ2333 题意概括 有N个节点,标号从1到N,这N个节点一开始相互不连通.第i个节点的初始权值为a[i ... 
- BZOJ2333:[SCOI2011]棘手的操作(Splay)
		Description 有N个节点,标号从1到N,这N个节点一开始相互不连通.第i个节点的初始权值为a[i],接下来有如下一些操作: U x y: 加一条边,连接第x个节点和第y个节点 A1 x v: ... 
- bzoj2333 [SCOI2011]棘手的操作(洛谷3273)
		题目描述 有N个节点,标号从1到N,这N个节点一开始相互不连通.第i个节点的初始权值为a[i],接下来有如下一些操作:U x y: 加一条边,连接第x个节点和第y个节点A1 x v: 将第x个节点的权 ... 
- bzoj2333  [SCOI2011]棘手的操作
		用set维护每个联通块里的最值,multiset维护所有块里的最值,并查集维护连通性,然后随便搞搞就行了,合并时候采用启发式合并.复杂度O(nlognlogn),大概勉强过的程度,反正跑的很慢就是了. ... 
随机推荐
- 循环 while
			day 2 ---------------------------------------------------把一件简单的事情做到极致,你就成功了. Day2作业及默写 1.判断下列逻辑语句的Tr ... 
- docker创建nginx+php-fpm+mysql环境(一分钟搭建lnmp)
			下载镜像 docker pull bitnami/php-fpm #下载php-fpm镜像 docker pull nginx #下载nginx镜像docker pull mysql:5.5.59 # ... 
- D1. Great Vova Wall (Version 1)
			链接 [https://codeforces.com/contest/1092/problem/D1] 题意 给你n个位置墙的高度,现在你有2×1 砖块,你可以竖直或者水平放置 问你是否可以使得所有位 ... 
- jQuery中.html(“xxx”)和.append("xxx")有什么区别
			append是追加,html是完全替换比如<p id="1"><p>123</p></p>$("#1").htm ... 
- js this的含义以及讲解
			this关键字是一个非常重要的语法点.毫不夸张地说,不理解它的含义,大部分开发任务都无法完成. 首先,this总是返回一个对象,简单说,就是返回属性或方法“当前”所在的对象. 下面来两个例子来让大家更 ... 
- 容错处理try
			var num = 90; try{ console.log( num + 100 ); consolel.log(aaa); }catch(e){ console.log("如果程序中有异 ... 
- JS 获取链接中的参数
			1.获取链接全部参数,以对象的形式返回 //获取url中参数 function GetRequest() { var url = location.search; //获取url中"?&qu ... 
- java lang(Comparable接口) 和java util(Comparator接口)分析比较
			//Comparable 接口强行对实现它的每个类的对象进行整体排序. -- 自然排序.类的compareTo称为自然比较方法. public interface Comparable<T> ... 
- vue-cli3.0之vue.config.js的配置项(注解)
			module.exports = { // 部署应用时的基本 URL baseUrl: process.env.NODE_ENV === 'production' ? '192.168.60.110: ... 
- git遇到的问题 .Git: There is no tracking information for the current branch.
			1.Git: There is no tracking information for the current branch. 在执行git pull的时候,提示当前branch没有跟踪信息: git ... 
