传送门


解析:

跟动态图屁关系没有,自己去读题啊,操作参数c≤7c \leq 7c≤7,没有最后两个断边的操作。

思路:

前777个显然都是平衡树随便做的东西吧,第六个稍微有点麻烦,不过只需要取一下对数就行了,就能化乘法为加法,double 就能存得下。

然而这道题有什么需要说的呢?

优化,以及卡常,作为BZOJ唯一两份卡进3s(目前)的代码之一的auther。我想说一些只能用在平衡树,而不能用在离线离散化后线段树上的优化。

思路:

首先平衡树相比线段树最大的优势是什么?

前期节点数较少的时候,平衡树的logloglog是不满的。

显然,这道题这么多操作,出题人肯定就不会专门卡某一种做法,数据有极大概率随机生成。

考虑怎么让平衡树的log尽量不满。

合并同权值。

然后就轻松卡进3s。

当然我这份代码至少还有三个地方可以优化掉一大堆常数。

有几个操作可以放在并查集里面进行,不过就需要记录平衡树中节点对应在哪个并查集里面,而且这个记录数组只会在222操作用到。就可以轻松卡进2s(预计)。

当然空间再开大一倍就不用每次回收内存了,又是巨大的优化(至于为什么是一倍空间,用势能法算一下就知道了)

不过懒得卡了。有兴趣的自己可以研究更多优化。


UPD:

去学了一下ODT,发现好像我写的就是ODT。

不过这道题最坏情况下ODT也能随便弄过去,还行。


代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define re register
#define gc get_char
#define pc put_char
#define cs constnamespace IO{namespace IOONLY{cs int Rlen=1<<20|1;char buf[Rlen],*p1,*p2;char obuf[Rlen],*p3=obuf;char ch[23];}inline char get_char(){using namespace IOONLY;return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,Rlen,stdin),p1==p2)?EOF:*p1++;}inline void put_char(char c){using namespace IOONLY;*p3++=c;if(p3==obuf+Rlen)fwrite(obuf,1,Rlen,stdout),p3=obuf;}inline void FLUSH(){using namespace IOONLY;fwrite(obuf,1,p3-obuf,stdout),p3=obuf;}inline int getint(){re int num;re char c;while(!isdigit(c=gc()));num=c^48;while(isdigit(c=gc()))num=(num+(num<<2)<<1)+(c^48);return num;}inline void outint(int a){using namespace IOONLY;if(a==0)pc('0');while(a)ch[++ch[0]]=a-a/10*10,a/=10;while(ch[0])pc(ch[ch[0]--]^48);}
}
using namespace IO;cs int N=400005;
namespace FHQ_treap{namespace Vars{int val[N];double vlog[N],sumlog[N];int siz[N],cnt[N];int son[N][2];int pri[N];int tot;int del[N],top;}int qn,q[N];inline int newnode(int _val,int _cnt=1){using namespace Vars;int now=top?del[top--]:++tot;val[now]=_val;vlog[now]=log2(_val);sumlog[now]=_cnt*vlog[now];siz[now]=cnt[now]=_cnt;son[now][0]=son[now][1]=0;pri[now]=rand()*RAND_MAX+rand();return now;}inline void pushup(int now){using namespace Vars;siz[now]=siz[son[now][0]]+siz[son[now][1]]+cnt[now];sumlog[now]=vlog[now]*cnt[now]+sumlog[son[now][0]]+sumlog[son[now][1]];}pair<int,int> split_key(int now,cs int &key){using namespace Vars;if(!now)return make_pair(0,0);pair<int,int> res;if(key<val[now]){res=split_key(son[now][0],key);son[now][0]=res.second;res.second=now;}else {res=split_key(son[now][1],key);son[now][1]=res.first;res.first=now;}pushup(now);return res;}int merge(int lc,int rc){using namespace Vars;if(!lc||!rc)return lc+rc;if(pri[lc]<pri[rc]||(pri[lc]==pri[rc]&&(rand()&1))){son[lc][1]=merge(son[lc][1],rc);pushup(lc);return lc;}else {son[rc][0]=merge(lc,son[rc][0]);pushup(rc);return rc;}}inline int Insert(int now,int key,cs int &_cnt=1){using namespace Vars;if(!now)return newnode(key,_cnt);pair<int,int> res1=split_key(now,key);pair<int,int> res2=split_key(res1.first,key-1);if(res2.second){cnt[res2.second]+=_cnt;pushup(res2.second);}else res2.second=newnode(key,_cnt);return merge(res2.first,merge(res2.second,res1.second));}void inorder_dfs(int now){using namespace Vars;if(!now)return ;inorder_dfs(son[now][0]);q[++qn]=now;inorder_dfs(son[now][1]);}inline int Join(int a,int b){using namespace Vars;if(!a||!b)return a+b;if(siz[a]>siz[b])swap(a,b);qn=0;inorder_dfs(a);for(int re i=1;i<=qn;++i){b=Insert(b,val[q[i]],cnt[q[i]]);del[++top]=q[i];}return b;}inline int updatemax(int now,int key){using namespace Vars;pair<int,int> res=split_key(now,key);if(!res.first)return res.second;int sze=siz[res.first];qn=0;inorder_dfs(res.first);for(int re i=1;i<=qn;++i)del[++top]=q[i];return Insert(res.second,key,sze);}inline int updatemin(int now,int key){using namespace Vars;pair<int,int> res=split_key(now,key-1);if(!res.second)return res.first;int sze=siz[res.second];qn=0;inorder_dfs(res.second);for(int re i=1;i<=qn;++i)del[++top]=q[i];return Insert(res.first,key,sze);}inline int query_Kth(int now,int Rank){using namespace Vars;while(now){if(siz[son[now][0]]<Rank&&siz[son[now][0]]+cnt[now]>=Rank)return val[now];if(Rank<=siz[son[now][0]])now=son[now][0];else Rank-=siz[son[now][0]]+cnt[now],now=son[now][1];}return 233333;}inline int compare(int a,int b){using namespace Vars;return sumlog[a]>sumlog[b];}inline int query_siz(int a){using namespace Vars;return siz[a];}
}
using namespace FHQ_treap;int Q;
int rt[N],tot;
int fa[N];
inline int getfa(int x){while(x^fa[x])x=fa[x]=fa[fa[x]];return x;
}inline void merge_uset(int u,int v){u=getfa(u);v=getfa(v);if(u==v)return ;fa[u]=v;if(Vars::siz[rt[u]]<Vars::siz[rt[v]])swap(u,v);rt[v]=rt[u]=Join(rt[u],rt[v]);
}signed main(){srand(time(0));Q=getint();while(Q--){int op=getint();switch(op){case 1:{rt[++tot]=newnode(getint());fa[tot]=tot;break;}case 2:{merge_uset(getint(),getint());break;}case 3:{int a=getfa(getint()),x=getint();rt[a]=updatemax(rt[a],x);break;}case 4:{int a=getfa(getint()),x=getint();rt[a]=updatemin(rt[a],x);break;}case 5:{int a=getfa(getint()),Rank=getint();outint(query_Kth(rt[a],Rank));pc('\n');break;}case 6:{int a=getfa(getint()),b=getfa(getint());outint(compare(rt[a],rt[b]));pc('\n');break;}case 7:{int a=getfa(getint());outint(query_siz(rt[a]));pc('\n');break;}}}FLUSH();return 0;
}

2019.01.17【BZOJ4399】 魔法少女LJJ(FHQ_treap)(ODT)相关推荐

  1. bzoj4399 魔法少女LJJ

    这题不愧为4399. 4399: 魔法少女LJJ Time Limit: 20 Sec  Memory Limit: 162 MB Submit: 622  Solved: 145 [Submit][ ...

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

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

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

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

  4. [BZOJ4399]魔法少女LJJ(线段树合并)

    请仔细阅读数据范围,c<=7. 线段树合并裸题,对于乘积大小比较,使用log即可. 1 #include<cmath> 2 #include<cstdio> 3 #inc ...

  5. [BZOJ4399]魔法少女LJJ

    题目大意: 一个动态图,支持以下$7$种操作: 1.加入一个权值为$x$的点: 2.在点$a$和点$b$之间加入一条无向边: 3.在点$a$所属的连通块中将小于$x$的所有权值修改为$x$: 4.在点 ...

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

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

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

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

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

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

  9. BZOJ 4399: 魔法少女LJJ

    4399: 魔法少女LJJ Time Limit: 20 Sec Memory Limit: 162 MB Submit: 287 Solved: 73 Description 在森林中见过会动的树, ...

  10. bzoj 4399 魔法少女LJJ

    4399: 魔法少女LJJ Time Limit: 20 Sec  Memory Limit: 162 MB http://www.lydsy.com/JudgeOnline/problem.php? ...

最新文章

  1. Servlet中的配置 web.xml
  2. 计算机网络模型到底是七层?五层?四层?
  3. (2017)第八届蓝桥杯大赛个人赛省赛(软件类) C/C++ 大学A组 题解(第八题包子凑数)
  4. 西里尔字 - 俄罗斯
  5. MySQL-主从复制监控
  6. 基于Xml 的IOC 容器-向容器注册
  7. junit mockito_从工作中清除代码–使用JUnit 5,Mockito和AssertJ编写可执行规范
  8. 让不同的库元件继承自共同的类
  9. 7-5 计算分段函数[3] (10 分)
  10. 利用批处理查看dll中的函数
  11. 关于CityEngine导入shp数据
  12. 线程的优先级(详细)
  13. xp系统如何更改计算机用户名,xp用administrator_XP系统修改administrator的用户名_xpadministrator...
  14. SOFA Weekly | QA 整理
  15. 货捕头API接口,item_search - 根据关键词取商品列表
  16. 万彩办公大师多页PDF文档去掉空白部分合并到同一页
  17. FFE均衡技术的原理、作用及特点
  18. 【历史上的今天】12 月 10 日:世界上第一位程序员诞生;Ada 语言发布;第一人称射击游戏的开拓者
  19. 使用realsense D435i实现机械臂对物体的自动抓取总结
  20. 使用Python 封装一个简单的Mysql工具类

热门文章

  1. 导致联想拯救者y7000触控板失灵的一种可能
  2. python画樱花树教程_turtle模块-知乎画樱花树
  3. 汉威危化品安全风险监测预警平台 助力企业摆脱新旧领域风险
  4. Factory Track 7 链接 Infor CloudSuite Industrial 10 操作设置
  5. 共享的快捷方式会经常突然不见_突然爆红的共享自习室,会是一个新风口吗?...
  6. matlab仿真限幅发散,基于模糊控制的直流电机调速系统MATLAB仿真_贾东耀
  7. 计算机网络DNS域名解析协议详解
  8. 最新Uniapp开发的多端影视APP+对接苹果CMS
  9. Spring Cloud 配置中心乱码解决
  10. Android Audio - 支持多个APK同时录音