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

#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. Ehcache基于java API实现

    上代码: package com.utils.cacheutils; import com.situopenapi.constant.EhcacheConstants; import com.situ ...

  2. frame3.5安装出错

    一般是因为禁用了microsoft update,可以在服务里禁用改为手动,之后启动,然后就可以安装

  3. 百度地图API定位+显示位置

    1. 先在需要嵌入地图的页面引入map.js <script src="http://api.map.baidu.com/api?v=2.0&ak=你的秘钥"> ...

  4. Discuz论坛搜索下拉框插件openSug

    Discuz!只需安装openSug插件即可获得带有“搜索框提示”功能的搜索框,让您的Discuz搜索更便捷! 下载:https://www.opensug.org/faq/.../opensug.d ...

  5. 【php】php 生僻知识点认知

    资料引用来源:http://www.runoob.com/php/php-tutorial.html ​ 表单提交中, 变量名中的点和空格被转换成下划线.例如 <input name=" ...

  6. 基于pygame的打砖块游戏,做到一半,不带做了

    跟着一个博主做的,前面的变量的定义全是内个哥们的,没带任何改动,就做了个界面,背景音乐,绘制了个小球,绘制了挡板 小球可以撞到边界反弹,然后做了砖块,定义了一个存放砖块的列表,,,就没有下文了 原博主 ...

  7. "Mon Dec 31 00:00:00 CST 2012" java日期装换 "yyyy-MM-dd"

    import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import ja ...

  8. R语言学习笔记(十六):构建分割点函数

    选取预测概率的分割点 cutoff<- function(n,p){ pp<-1 i<-0 while (pp>=0.02) { model.predfu<-rep(&q ...

  9. python2.7练习小例子(十九)

        19):题目:一球从100米高度自由落下,每次落地后反跳回原高度的一半:再落下,求它在第10次落地时,共经过多少米?第10次反弹多高? #!/usr/bin/python # -*- codi ...

  10. python基础之IO模型

    IO模型分类 五种IO Model blocking IO 阻塞IO nonblocking IO 非阻塞IO IO multiplexing IO多路复用 signal driven IO 信号驱动 ...