注意到只有增加点/合并的操作。这些操作都可以用线段树完成,于是线段树合并一发就好了。注意乘积大小直接比较肯定会炸,取个对数即可。数据中存在重边。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
int read()
{
int x=,f=;char c=getchar();
while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
}
#define N 400010
#define inf 1000000000
int m,tot,fa[N],root[N],cnt;
int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
struct data{int l,r,s;double v;bool f;
}tree[N*];
void up(int k)
{
tree[k].s=tree[tree[k].l].s+tree[tree[k].r].s;
tree[k].v=tree[tree[k].l].v+tree[tree[k].r].v;
}
void down(int k)
{
tree[tree[k].l].f=tree[tree[k].r].f=;
tree[tree[k].l].s=tree[tree[k].r].s=;
tree[tree[k].l].v=tree[tree[k].r].v=;
tree[k].f=;
}
void ins(int &k,int l,int r,int x,int s,double y)
{
if (!k) k=++cnt;
tree[k].v+=y;tree[k].s+=s;
if (l==r) return;
if (tree[k].f) down(k);
int mid=l+r>>;
if (x<=mid) ins(tree[k].l,l,mid,x,s,y);
else ins(tree[k].r,mid+,r,x,s,y);
}
int merge(int x,int y,int l,int r)
{
if (!x||!y) return x|y;
tree[x].s+=tree[y].s,tree[x].v+=tree[y].v;
if (l<r)
{
if (tree[x].f) down(x);if (tree[y].f) down(y);
int mid=l+r>>;
tree[x].l=merge(tree[x].l,tree[y].l,l,mid);
tree[x].r=merge(tree[x].r,tree[y].r,mid+,r);
}
return x;
}
int modify(int k,int l,int r,int x,int y)
{
if (x>y||!k) return ;
if (l==x&&r==y)
{
int p=tree[k].s;
tree[k].s=,tree[k].v=,tree[k].f=;
return p;
}
if (tree[k].f) down(k);
int mid=l+r>>,ans;
if (y<=mid) ans=modify(tree[k].l,l,mid,x,y);
else if (x>mid) ans=modify(tree[k].r,mid+,r,x,y);
else ans=modify(tree[k].l,l,mid,x,mid)+modify(tree[k].r,mid+,r,mid+,y);
up(k);
return ans;
}
int query(int k,int l,int r,int x)
{
if (l==r) return l;
if (tree[k].f) down(k);
int mid=l+r>>;
if (tree[tree[k].l].s>=x) return query(tree[k].l,l,mid,x);
else return query(tree[k].r,mid+,r,x-tree[tree[k].l].s);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("bzoj4399.in","r",stdin);
freopen("bzoj4399.out","w",stdout);
const char LL[]="%I64d\n";
#else
const char LL[]="%lld\n";
#endif
m=read();
while (m--)
{
int op=read();
switch(op)
{
case :
{
fa[++tot]=tot;int x=read();
ins(root[tot],,inf,x,,log(x));
break;
}
case :
{
int x=find(read()),y=find(read());
if (x!=y) root[x]=merge(root[x],root[y],,inf);
fa[y]=x;
break;
}
case :
{
int p=find(read()),x=read();
int s=modify(root[p],,inf,,x-);
ins(root[p],,inf,x,s,s*log(x));
break;
}
case :
{
int p=find(read()),x=read();
int s=modify(root[p],,inf,x+,inf);
ins(root[p],,inf,x,s,s*log(x));
break;
}
case :
{
int p=find(read()),x=read();
printf("%d\n",query(root[p],,inf,x));
break;
}
case :
{
int x=find(read()),y=find(read());
printf("%d\n",tree[root[x]].v>tree[root[y]].v);
break;
}
case :
{
int x=find(read());
printf("%d\n",tree[root[x]].s);
break;
}
}
}
return ;
}

BZOJ4399 魔法少女LJJ(线段树合并)的更多相关文章

  1. BZOJ4399魔法少女LJJ——线段树合并+并查集

    题目描述 在森林中见过会动的树,在沙漠中见过会动的仙人掌过后,魔法少女LJJ已经觉得自己见过世界上的所有稀奇古怪的事情了LJJ感叹道“这里真是个迷人的绿色世界,空气清新.淡雅,到处散发着醉人的奶浆味: ...

  2. bzoj4399 魔法少女LJJ 线段树合并

    只看题面绝对做不出系列.... 注意到\(c \leqslant 7\),因此不会有删边操作(那样例删边干嘛) 注意到\(2, 5\)操作十分的有趣,启示我们拿线段树合并来做 操作\(7\)很好处理 ...

  3. bzoj4399 魔法少女LJJ 线段树合并+线段树二分+并查集

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4399 题解 毒瘤题 \(9\) 种操作还有支持动态图的连通性 仔细读题 $ c<=7$. ...

  4. 【BZOJ4399】魔法少女LJJ 线段树合并

    [BZOJ4399]魔法少女LJJ Description 在森林中见过会动的树,在沙漠中见过会动的仙人掌过后,魔法少女LJJ已经觉得自己见过世界上的所有稀奇古怪的事情了LJJ感叹道“这里真是个迷人的 ...

  5. BZOJ 4399: 魔法少女LJJ 线段树合并 + 对数

    Description 在森林中见过会动的树,在沙漠中见过会动的仙人掌过后,魔法少女LJJ已经觉得自己见过世界上的所有稀奇古怪的事情了LJJ感叹道“这里真是个迷人的绿色世界,空气清新.淡雅,到处散发着 ...

  6. BZOJ.4399.魔法少女LJJ(线段树合并)

    BZOJ 注意\(c\leq7\)→_→ 然后就是裸的权值线段树+线段树合并了. 对于取\(\max/\min\)操作可以直接区间修改清空超出范围的值,然后更新到对应位置上就行了(比如对\(v\)取\ ...

  7. 魔法少女 LJJ——线段树

    题目 [题目描述] 在森林中见过会动的树,在沙漠中见过会动的仙人掌过后,魔法少女 LJJ 已经觉得自己见过世界上的所有稀奇古怪的事情了. LJJ 感叹道“这里真是个迷人的绿色世界,空气清新.淡雅,到处 ...

  8. BZOJ 4399: 魔法少女LJJ(线段树)

    传送门 解题思路 出题人真会玩..操作\(2\)线段树合并,然后每棵线段树维护元素个数和.对于\(6\)这个询问,因为乘积太大,所以要用对数.时间复杂度\(O(nlogn)\) 代码 #include ...

  9. BZOJ4399 魔法少女LJJ【线段树合并】【并查集】

    Description 在森林中见过会动的树,在沙漠中见过会动的仙人掌过后,魔法少女LJJ已经觉得自己见过世界上的所有稀奇古怪的事情了 LJJ感叹道"这里真是个迷人的绿色世界,空气清新.淡雅 ...

随机推荐

  1. mysql数据库和数据表的简单操作

    一.数据库的增删改查 1.新建数据库 CREATE DATABASE 数据库名 charset utf8; 数据库名规则:可以由字母.数字.下划线.@.#.$ 区分大小写, 不能使用关键字如 crea ...

  2. PHP基础 (麦子学院 第二阶段)

    zendstudio 10.0破解版,新建完项目后,首先修改项目的编码方式,统一改成utf-8 (选中项目,再右键properties:Text file encoding).修改字体大小. apac ...

  3. python3 练习题100例 (二十五)打印一个n层金字塔

    题目内容: 打印一个n层(1<n<20)金字塔,金字塔由“+”构成,塔尖是1个“+”,下一层是3个“+”,居中排列,以此类推. 注意:每一行的+号之后均无空格,最后一行没有空格. 输入格式 ...

  4. python3爬虫之开篇

    写在前面的话: 折腾爬虫也有一段时间了,从一开始的懵懵懂懂,到现在的有一定基础,对于这一路的跌跌撞撞,个人觉得应该留下一些文字性的东西,毕竟好记性不如烂笔头,而且毕竟这是吃饭的家伙,必须用心对待才可以 ...

  5. Verilog学习笔记基本语法篇(七)········ 生成块

    生成块可以动态的生成Verilog代码.可以用于对矢量中的多个位进行重复操作.多个模块的实例引用的重复操作.根据参数确定程序中是否包含某段代码.生成语句可以控制变量的声明.任务和函数的调用.还能对实例 ...

  6. NO-ZERO(空格补全)

    The NO-ZERO command follows the DATA statement REPORT Z_Test123_01. DATA: W_NUR(10) TYPE N. MOVE 50 ...

  7. abap<itab>refresh,clear,free

    在ABAP开发过程中,clear,refresh,free都有用来清空内表的作用,但用法还是有区别的. clear itab,清空内表行以及工作区,但保存内存区. clear itab[],清空内表行 ...

  8. Spring + MySQL + Mybatis + Redis【二级缓存】执行流程分析

    一级缓存基于 PerpetualCache 的 HashMap 本地缓存,其存储作用域为 Session,当 Session flush 或 close 之后,该Session中的所有 Cache 就 ...

  9. WPF把CheckBox的文字放到左边,开关在右边

    原文:WPF把CheckBox的文字放到左边,开关在右边 效果 实现 这篇文章给了一个不错的参考方案. http://www.codeproject.com/Articles/19141/WPF-Ch ...

  10. 单服务器最大tcp连接数及调优汇总

    启动线程数: 启动线程数=[任务执行时间/(任务执行时间-IO等待时间)]*CPU内核数 最佳启动线程数和CPU内核数量成正比,和IO阻塞时间成反比.如果任务都是CPU计算型任务,那么线程数最多不超过 ...