【bzoj4399】魔法少女LJJ 并查集+权值线段树合并

题目描述

在森林中见过会动的树,在沙漠中见过会动的仙人掌过后,魔法少女LJJ已经觉得自己见过世界上的所有稀奇古怪的事情了
LJJ感叹道“这里真是个迷人的绿色世界,空气清新、淡雅,到处散发着醉人的奶浆味;小猴在枝头悠来荡去,好不自在;各式各样的鲜花争相开放,各种树枝的枝头挂满沉甸甸的野果;鸟儿的歌声婉转动听,小河里飘着落下的花瓣真是人间仙境”
SHY觉得LJJ还是太naive,一天,SHY带着自己心爱的图找到LJJ,对LJJ说:“既然你已经见识过动态树,动态仙人掌了,那么今天就来见识一下动态图吧”
LJJ:“要支持什么操作?”
SHY:“
1.新建一个节点,权值为x。
2.连接两个节点。
3.将一个节点a所属于的联通快内权值小于x的所有节点权值变成x。
4.将一个节点a所属于的联通快内权值大于x的所有节点权值变成x。
5.询问一个节点a所属于的联通块内的第k小的权值是多少。
6.询问一个节点a所属联通快内所有节点权值之积与另一个节点b所属联通快内所有节点权值之积的大小。
7.询问a所在联通快内节点的数量
8.若两个节点a,b直接相连,将这条边断开。
9.若节点a存在,将这个点删去。

LJJ:“我可以离线吗?”
SHY:“可以,每次操作是不加密的,”
LJJ:“我可以暴力吗?”
SHY:“自重”
LJJ很郁闷,你能帮帮他吗

(事实上,仔细读题可以发现,出题人在数据范围中约定了$c\le 7$,因此第8、9种操作是不存在的!这里也将样例作了修改)

输入

第一行有一个正整数m,表示操作个数。
接下来m行,每行先给出1个正整数c。
若c=1,之后一个正整数x,表示新建一个权值为x的节点,并且节点编号为n+1(当前有n个节点)。
若c=2,之后两个正整数a,b,表示在a,b之间连接一条边。
若c=3,之后两个正整数a,x,表示a联通快内原本权值小于x的节点全部变成x。
若c=4,之后两个正整数a,x,表示a联通快内原本权值大于x的节点全部变成x。
若c=5,之后两个正整数a,k,表示询问a所属于的联通块内的第k小的权值是多少。
若c=6,之后两个正整数a,b,表示询问a所属联通快内所有节点权值之积与b所属联通快内所有节点权值之积的大小,
若a所属联通快内所有节点权值之积大于b所属联通快内所有节点权值之积,输出1,否则为0。
若c=7,之后一个正整数a,表示询问a所在联通块大小
若c=8,之后两个正整数a,b,表示断开a,b所连接的边。
若c=9,之后一个正整数a,表示断开a点的所有连边
具体输出格式见样例

输出

对于每个询问,输出答案

样例输入

11
1 2
1 3
1 4
1 5
1 6
2 1 2
2 2 3
2 3 4
2 4 5
3 2 5
5 3 4

样例输出

5


题解

并查集+权值线段树合并(本题是道语文题= =)

对于操作1、2、3、4、5、7,稍有做题经验的人很容易想到使用并查集维护连通块,对每个连通块开一棵权值线段树。

连边操作直接权值线段树合并,各种查询直接裸上线段树的区间查询。

对于3、4操作,可以先统计出有多少个数小于/大于x,然后删除所有小于/大于x的数,并在x位置加上这些数。

而对于6操作出现了乘积不是很好处理,我们把它取对数,因为$\log(nm)=\log n+\log m$,所以转化为每个数的对数的和,直接维护区间权值和即可。本题中使用double不会被卡精度。

时间复杂度$O(m\log n)$。

然而比$O(m\log n+n\log^2n)$的平衡树启发式合并还慢什么鬼。。

#include <cmath>
#include <cstdio>
#include <algorithm>
#define N 400010
#define lson l , mid , ls[x]
#define rson mid + 1 , r , rs[x]
using namespace std;
const int m = 1000000000;
int ls[N * 19] , rs[N * 19] , si[N * 19] , tot , root[N] , f[N] , n;
double sum[N * 19];
bool tag[N * 19];
void pushdown(int x)
{if(tag[x]){si[ls[x]] = si[rs[x]] = 0 , sum[ls[x]] = sum[rs[x]] = 0;tag[ls[x]] = tag[rs[x]] = 1 , tag[x] = 0;}
}
int find(int x)
{return x == f[x] ? x : f[x] = find(f[x]);
}
void add(int p , int a , double v , int l , int r , int &x)
{if(!x) x = ++tot;si[x] += a , sum[x] += a * v;if(l == r) return;pushdown(x);int mid = (l + r) >> 1;if(p <= mid) add(p , a , v , lson);else add(p , a , v , rson);
}
void del(int b , int e , int l , int r , int x)
{if(!x) return;if(b <= l && r <= e){si[x] = 0 , sum[x] = 0 , tag[x] = 1;return;}pushdown(x);int mid = (l + r) >> 1;if(b <= mid) del(b , e , lson);if(e > mid) del(b , e , rson);si[x] = si[ls[x]] + si[rs[x]] , sum[x] = sum[ls[x]] + sum[rs[x]];
}
int querysi(int b , int e , int l , int r , int x)
{if(!x) return 0;if(b <= l && r <= e) return si[x];pushdown(x);int mid = (l + r) >> 1 , ans = 0;if(b <= mid) ans += querysi(b , e , lson);if(e > mid) ans += querysi(b , e , rson);return ans;
}
int find(int k , int l , int r , int x)
{if(l == r) return l;pushdown(x);int mid = (l + r) >> 1;if(k <= si[ls[x]]) return find(k , lson);else return find(k - si[ls[x]] , rson);
}
int merge(int x , int y)
{if(!x) return y;if(!y) return x;si[x] += si[y] , sum[x] += sum[y];pushdown(x) , pushdown(y);ls[x] = merge(ls[x] , ls[y]) , rs[x] = merge(rs[x] , rs[y]);return x;
}
int main()
{int q , c , x , y , t;scanf("%d" , &q);while(q -- ){scanf("%d%d" , &c , &x);switch(c){case 1: add(x , 1 , log(x) , 1 , m , root[++n]) , f[n] = n; break;case 2:{scanf("%d" , &y) , x = find(x) , y = find(y);if(x != y) f[y] = x , root[x] = merge(root[x] , root[y]);break;}case 3:{x = find(x) , scanf("%d" , &y) , t = querysi(1 , y , 1 , m , root[x]);del(1 , y , 1 , m , root[x]) , add(y , t , log(y) , 1 , m , root[x]);break;}case 4:{x = find(x) , scanf("%d" , &y) , t = querysi(y , m , 1 , m , root[x]);del(y , m , 1 , m , root[x]) , add(y , t , log(y) , 1 , m , root[x]);break;}case 5: x = find(x) , scanf("%d" , &y) , printf("%d\n" , find(y , 1 , m , root[x])); break;			case 6: x = find(x) , scanf("%d" , &y) , y = find(y) , printf("%d\n" , sum[root[x]] > sum[root[y]]); break;default: x = find(x) , printf("%d\n" , si[root[x]]);}}return 0;
}

 

 

转载于:https://www.cnblogs.com/GXZlegend/p/7423642.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/400036.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

树莓派Raspbian Buster/Debian 10 安装ROS

目录一些补充安装ROS初始化rosdep测试平台&#xff1a;树莓派4B 系统版本&#xff1a; 2020-05-27-raspios-buster-arm64.img 一些补充 系统安装参考 【树莓派学习笔记】一、烧录系统、(无屏幕)配置Wifi和SSH服务 【树莓派学习笔记】二、(无屏幕)SSH远程登录、图形界面及系统…

pjsip视频通信开发(上层应用)之EditText重写

我们经常使用手机的打电话功能&#xff0c;当我们按键盘的时候&#xff0c;有一个地方显示我们按键的内容&#xff0c;当我们的手点击那个地方的时候&#xff0c;并没有弹出软件盘&#xff0c;所以我们再有数字键盘的时候&#xff0c;要屏蔽系统的软件盘。 我们分析一下&#x…

JavaWeb重要知识点总结

JavaWeb学习篇之----容器Response详解http://blog.csdn.net/jiangwei0910410003/article/details/22886847获得所有请求头名称和头信息java.util.Enumeration names request.getHeaderNames();System.out.println("");while(names.hasMoreElements()){String name …

pycharm 中HTML代码的对齐

以前用sublime &#xff0c;现在django要在pycharm编辑html&#xff0c;要实现html的格式化&#xff0c; 用快捷键 CtrlAltL 非常实用

树莓派安装Ubuntu MATE及ROS系统

目录解锁SSH换源安装VNC服务安装ROS初始化rosdep和环境测试平台&#xff1a;树莓派4B 系统版本&#xff1a; ubuntu-mate-20.04.1-desktop-armhfraspi.img 在Raspberry Pi Download Options下载系统镜像 在树莓派资源下载 | 树莓派实验室下载工具 使用SDForm…

mysql 清空表的两种方法

一、Delete DELETE FROM table; 二、Truncate TRUNCATE table; 第一种方法其实就是去掉where条件&#xff0c;没有了条件&#xff0c;也就是删除掉表里面的所有记录了&#xff1b; 第二种方法像是重置表&#xff0c;把表中内容全部清除&#xff0c;回到刚建好表的状态&#xff…

jQuery学习笔记(四)

jQuery对表单、表格的操作及更多应用 表单应用 一个表单组成部分&#xff1a; 表单标签、表单域及表单按钮 单行文本框应用获取和失去焦点事件 $(function(){ $(":input").focus(function(){ //获取焦点触发事件 $(this).addClass("focus"); //增加样…

Flask最强攻略 - 跟DragonFire学Flask - 第四篇 Flask 中的模板语言 Jinja2 及 render_template 的深度用法

https://www.cnblogs.com/DragonFire/p/9259999.html 是时候开始写个前端了,Flask中默认的模板语言是Jinja2 现在我们来一步一步的学习一下 Jinja2 捎带手把 render_template 中留下的疑问解决一下 首先我们要在后端定义几个字符串,用于传递到前端 STUDENT {name: Old, age:…

【Jetson Nano学习笔记】1. 系统镜像和ROS的安装

目录安装系统换源安装VNC服务安装ROS初始化rosdep和环境测试平台&#xff1a;Jetson Nano 系统版本&#xff1a;4.6.1 安装系统 在Jetson Download Center下载镜像&#xff1a; 在树莓派资源下载 | 树莓派实验室下载工具 使用SDFormatter格式化内存卡 使用balenaEtcher烧录镜…

我的Android进阶之旅------Android利用Sensor(传感器)实现水平仪功能的小例

这里介绍的水平仪&#xff0c;指的是比较传统的气泡水平仪&#xff0c;在一个透明圆盘内充满液体&#xff0c;液体中留有一个气泡&#xff0c;当一端翘起时&#xff0c;该气泡就会浮向翘起的一端。 利用方向传感器返回的第一个参数&#xff0c;实现了一个指南针小应用。我的And…

【linux命令总结】——后续用到的内容持续补充和更新

比如说&#xff1a;某个文件是go文件&#xff0c;名字叫做 Hello.go 1、通过后台运行某个程序&#xff0c;将结果输出到某个文件&#xff0c; 如果是直接运行go程序&#xff1a;go run Hello.go 后台运行&#xff1a;nohup go run Hello.go & &#xff0c;然后就会将结果输…

【Jetson Nano学习笔记】2. ORB-SLAM3及ZED 2i驱动安装

目录ZED 2i驱动安装安装驱动自测ROS测试zed2i.launchrostopic listrosnode listdisplay_zed2i.launchzed_rtabmap.launchORB-SLAM3安装OpenCV 3安装Glew安装Pangolin安装boost安装Eigen 3安装OpenGL安装openssl安装ORB-SLAM3建立swap准备编译编译关闭swap平台&#xff1a;Jetso…

给超链接(a标签)加onclick事件

<a onclick"alert(1)">超链接1</a><br> <a href"#" onclick"alert(2)">超链接2</a> <br> <a href"javascript:alert(3)">超链接3</a>

proj1088

滑雪Time Limit: 1000MS Memory Limit: 65536KTotal Submissions: 69608 Accepted: 25669Description Michael喜欢滑雪百这并不奇怪&#xff0c; 因为滑雪的确很刺激。可是为了获得速度&#xff0c;滑的区域必须向下倾斜&#xff0c;而且当你滑到坡底&#xff0c;你不得不再次走…

【Jetson Nano学习笔记】3. ORB-SLAM3运行双目Demo(ZED 2i)

目录修改zed-ros-wrapper的参数双目测试平台&#xff1a;Jetson Nano 系统版本&#xff1a;4.6.1 参考资料&#xff1a; zed-ros-wrapper —— ROS Wiki ZED 相机 && ORB-SLAM2安装环境配置与ROS下的调试 —— 李小铭 又一遍……ORB_SLAM2ZED相机(SDK2.2.1)CUDA9.0ROS…

PyCharm设置自动换行

在使用PyCharm码代码的时候&#xff0c;有些单行的代码比较长&#xff0c;经常需要手动拉动滚动条。 辣么怎么设置自动换行呢&#xff1f;&#xff1f; 敲黑板 在这里给大家介绍两种方式&#xff1a; 1、如果你需要频繁在【自动换行/非自动换行】模式中切换 那就需要设置一个顺…

邮件服务

http://linuxsogood.org/1121.html/comment-page-1 转载于:https://www.cnblogs.com/saolv/p/7440536.html

MySQL数据库和ACID模型

2019独角兽企业重金招聘Python工程师标准>>> ACID模型是一组强调高可靠性的数据库系统设计原则。InnoDB存储引擎坚持ACID原则&#xff0c;确保即使在软件崩溃甚至是硬件故障的情况下&#xff0c;数据也不会损坏。当你需要依赖兼容ACID原则的业务时&#xff0c;你不必…

MFC中SQLite数据库的使用

1打开数据库 BOOL playDlg::openData() { WCHAR a[100]; CString path; path m_exePathL"sentence_making\\FROG.db"; memcpy(a,path,sizeof(a)); int nRet sqlite3_open16((const char *)a,&pSQLite); // 链接到数据库&#xff0c;如果成功&#xff0c;数据…

【Jetson Nano学习笔记】4. python 3编译bridge

目录使用python3编译boostconsole_bridgepython3bridge平台&#xff1a;Jetson Nano 系统版本&#xff1a;4.6.1 参考资料&#xff1a; How to setup ROS with Python 3 Unable to use cv_bridge with ROS Kinetic and Python3 CMake Error &#xff1a;Could not find a pac…