BZOJ 4399: 魔法少女LJJ 线段树合并 + 对数
Description
在森林中见过会动的树,在沙漠中见过会动的仙人掌过后,魔法少女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很郁闷,你能帮帮他吗
Input
第一行有一个正整数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点的所有连边
具体输出格式见样例
Output
这是一道语文题 + 高中数学题.
这里最困难的是第 $6$ 问,询问两个联通快乘积的大小关系.
显然不可以直接乘起来 (你想写高精度也行).
高中数学告诉我们,$log_{x}(a\times b)=log_{x}(a)+log_{x}(b)$,而 $log_{x}$ 在 $x>=1$ 时是增函数.
所以只需比较区间 $\sum log$ 的大小就可以比较出乘积的大小.
这个方法还真是听巧妙的.
#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;
#define ls lson[x]
#define rs rson[x]
#define setIO(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
const int maxn=500000;
const int N=1000000000;
namespace IO {
char *p1,*p2,buf[100000];
#define nc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++)
int rd() {
int x=0;
char c=nc();
while(c<48) c=nc();
while(c>47) x=(((x<<2)+x)<<1)+(c^48),c=nc();
return x;
}
};
struct UFS {
int p[maxn];
void init() {
for(int i=0;i<maxn;++i) p[i]=i;
}
int find(int x) {
return p[x]==x?x:p[x]=find(p[x]);
}
}tr;
int cnt;
int rt[maxn],lson[maxn*10],rson[maxn*10],num[maxn*10];
double de[maxn*10];
int newnode() {
return ++cnt;
}
void pushup(int x) {
num[x]=num[ls]+num[rs];
de[x]=de[ls]+de[rs];
}
void update(int &x,int l,int r,int p,int v) {
if(!x)x=newnode();
if(l==r) {
num[x]+=v, de[x]+=(double)v*(double)(log(p));
return;
}
int mid=(l+r)>>1;
if(p<=mid) update(ls,l,mid,p,v);
else update(rs,mid+1,r,p,v);
pushup(x);
}
int merge(int x,int y) {
if(!x||!y) return x+y;
num[x]+=num[y];
de[x]+=de[y];
lson[x]=merge(lson[x],lson[y]);
rson[x]=merge(rson[x],rson[y]);
return x;
}
int less(int &x,int l,int r,int k) {
if(!x||l>=k) return 0;
int re=0;
if(r<k) {
re=num[x],x=0;
return re;
}
if(l==r) return 0;
int mid=(l+r)>>1;
re+=less(ls,l,mid,k);
re+=less(rs,mid+1,r,k);
pushup(x);
return re;
}
int bigger(int &x,int l,int r,int k) {
if(!x||r<=k) return 0;
int re=0;
if(l>k) {
re=num[x],x=0;
return re;
}
if(l==r) return 0;
int mid=(l+r)>>1;
re+=bigger(ls,l,mid,k);
re+=bigger(rs,mid+1,r,k);
pushup(x);
return re;
}
int kth(int x,int l,int r,int k) {
if(l==r) return l;
int mid=(l+r)>>1;
if(k>num[ls]) return kth(rs,mid+1,r,k-num[ls]);
else return kth(ls,l,mid,k);
}
int main() {
using namespace IO;
int m,cc=0;
m=rd();
tr.init();
for(int cas=1;cas<=m;++cas) {
int op=rd();
if(op==1) {
int x=rd();
++cc;
update(rt[cc],1,N,x,1);
}
if(op==2) {
int x,y,a,b;
x=rd(),y=rd();
a=tr.find(x),b=tr.find(y);
if(a!=b) {
rt[b]=merge(rt[a],rt[b]);
tr.p[a]=b;
}
}
if(op==3) {
int a,x,c=0;
a=rd(),x=rd();
a=tr.find(a);
c=less(rt[a],1,N,x);
update(rt[a],1,N,x,c);
}
if(op==4) {
int a,x,c=0;
a=rd(),x=rd();
a=tr.find(a);
c=bigger(rt[a],1,N,x);
update(rt[a],1,N,x,c);
}
if(op==5) {
int a,k;
a=rd(),k=rd();
a=tr.find(a);
printf("%d\n",kth(rt[a],1,N,k));
}
if(op==6) {
int a,b;
a=rd(),b=rd();
a=tr.find(a),b=tr.find(b);
if(de[rt[a]]>de[rt[b]]) printf("1\n");
else printf("0\n");
}
if(op==7) {
int a;
a=rd();
a=tr.find(a);
printf("%d\n",num[rt[a]]);
}
}
return 0;
}
BZOJ 4399: 魔法少女LJJ 线段树合并 + 对数的更多相关文章
- BZOJ.4399.魔法少女LJJ(线段树合并)
BZOJ 注意\(c\leq7\)→_→ 然后就是裸的权值线段树+线段树合并了. 对于取\(\max/\min\)操作可以直接区间修改清空超出范围的值,然后更新到对应位置上就行了(比如对\(v\)取\ ...
- BZOJ 4399: 魔法少女LJJ(线段树)
传送门 解题思路 出题人真会玩..操作\(2\)线段树合并,然后每棵线段树维护元素个数和.对于\(6\)这个询问,因为乘积太大,所以要用对数.时间复杂度\(O(nlogn)\) 代码 #include ...
- BZOJ4399魔法少女LJJ——线段树合并+并查集
题目描述 在森林中见过会动的树,在沙漠中见过会动的仙人掌过后,魔法少女LJJ已经觉得自己见过世界上的所有稀奇古怪的事情了LJJ感叹道“这里真是个迷人的绿色世界,空气清新.淡雅,到处散发着醉人的奶浆味: ...
- 【BZOJ4399】魔法少女LJJ 线段树合并
[BZOJ4399]魔法少女LJJ Description 在森林中见过会动的树,在沙漠中见过会动的仙人掌过后,魔法少女LJJ已经觉得自己见过世界上的所有稀奇古怪的事情了LJJ感叹道“这里真是个迷人的 ...
- bzoj4399 魔法少女LJJ 线段树合并
只看题面绝对做不出系列.... 注意到\(c \leqslant 7\),因此不会有删边操作(那样例删边干嘛) 注意到\(2, 5\)操作十分的有趣,启示我们拿线段树合并来做 操作\(7\)很好处理 ...
- bzoj4399 魔法少女LJJ 线段树合并+线段树二分+并查集
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4399 题解 毒瘤题 \(9\) 种操作还有支持动态图的连通性 仔细读题 $ c<=7$. ...
- bzoj 4399 魔法少女LJJ
4399: 魔法少女LJJ Time Limit: 20 Sec Memory Limit: 162 MBhttp://www.lydsy.com/JudgeOnline/problem.php?i ...
- BZOJ 4399 魔法少女LJJ(线段树合并)
题意 https://www.lydsy.com/JudgeOnline/problem.php?id=4399 思路 码农题,需要一定代码功底.方法很暴力,先将权值离散,表示在线段树里储存的位置,每 ...
- 魔法少女 LJJ——线段树
题目 [题目描述] 在森林中见过会动的树,在沙漠中见过会动的仙人掌过后,魔法少女 LJJ 已经觉得自己见过世界上的所有稀奇古怪的事情了. LJJ 感叹道“这里真是个迷人的绿色世界,空气清新.淡雅,到处 ...
随机推荐
- 深入理解java:2.3.4. 并发编程concurrent包 之容器ConcurrentLinkedQueue(非阻塞的并发队列---循环CAS)
1. 引言 在并发编程中我们有时候需要使用线程安全的队列. 如果我们要实现一个线程安全的队列有两种实现方式:一种是使用阻塞算法,另一种是使用非阻塞算法. 使用阻塞算法的队列可以用一个锁(入队和出 ...
- Jmeter 04 Jmeter变量的使用
在使用jmeter进行接口测试时,我们难免会遇到需要从上下文中获取测试数据的情况,这个时候就需要引入变量了. 定义变量 添加->配置元件->用户自定义的变量 添加->配置元件-> ...
- String.equals()方法、整理String类的Length()、charAt()、 getChars()、replace()、 toUpperCase()、 toLowerCase()、trim()、toCharArray()
equals 是比较的两个字符串是否一样 length() 返回字符串的长度 charAt (int index) 返回index所指定的字符 getChars(int srcBegin,int sr ...
- thread 多线程2
###24.04_多线程(多线程程序实现的方式1)(掌握) * 1.继承Thread * 定义类继承Thread * 重写run方法 * 把新线程要做的事写在run方法中 * 创建线程对象 * 开启新 ...
- php多域名单站点路由
能够使多域名但是只有一个站点的小站,通过路由访问到各个指定目录 <?php //域名跳转路由 //默认跳转 $default = "http://www.stanwind.com/in ...
- Python Set intersection() 方法
描述 intersection() 方法用于返回两个或更多集合中都包含的元素,即交集. 语法 intersection() 方法语法: set.intersection(set1, set2 ... ...
- Bootstrap中DropDown插件显示下拉列表,点击下拉列表区域,不会再自动关闭。
目标: Bootstrap中DropDown插件显示下拉列表,点击下拉列表区域,不会再自动关闭. 参考:http://v3.bootcss.com/javascript/#dropdowns / ...
- [转载]神经网络偏置项(bias)的设置及作用
[转载]神经网络偏置项(bias)的设置及作用 原文来自:https://www.cnblogs.com/shuaishuaidefeizhu/p/6832541.html 1.什么是bias? 偏置 ...
- YOLOv3训练过程笔记
本人使用的是linux平台,按照YOLO网页0https://pjreddie.com/darknet/yolo/的步骤操作进行下载darkenet程序包以及编译,之后可尝试用VOC2007的数据集测 ...
- SQL 基础语句整理
SQL教程 SELECT 语句 SELECT * FROM 表名称 DISTINCT 语句 SELECT DISTINCT 列名称 FROM 表名称 SELECT LastName,FirstName ...