BZOJ[4399]魔法少女LJJ 线段树合并
来源:互联网 发布:php简单计算器代码 编辑:程序博客网 时间:2024/06/11 17:57
题目链接http://www.lydsy.com/JudgeOnline/problem.php?id=4399
c<=7!!c<=7!!c<=7!!
每新建一个节点,就开一个权值线段树,在连接时将两个线段树合并即可,对于操作3,4,直接查找比k大/小的数有多少个,查找时顺便将范围内的点删除,再全放在k上即可
操作五像平衡树那样随便搞一搞就可以了..
对于操作六,根据对数的运算性质
代码如下:
#include<ctype.h>#include<cstdio>#include<cmath>#define N 400050using namespace std;const int INF=1000000000;inline int read(){ int x=0,f=1;char c; do c=getchar(),f=c=='-'?-1:f; while(!isdigit(c)); do x=(x<<3)+(x<<1)+c-'0',c=getchar(); while(isdigit(c)); return x*f;}int n,t,x,y,k,top;int f[N];int Find(int k){ if(f[k]==k) return k; return f[k]=Find(f[k]);}struct Node{ int l,r,sum; double sum1; Node *ls,*rs; Node(int,int); inline void maintain(){ sum=ls->sum+rs->sum; sum1=ls->sum1+rs->sum1; return; }}*root[N],*null;Node::Node(int _,int __):l(_),r(__){ ls=rs=null; sum1=sum=0;}void Merge(Node *&x,Node *&y){ if(y==null) return; if(x==null){ x=y; return; } x->sum+=y->sum; x->sum1+=y->sum1; Merge(x->ls,y->ls);Merge(x->rs,y->rs);}void Insert(int x,int v,Node *&k,int L,int R){ if(k==null) k=new Node(L,R); if(k->l==k->r){ k->sum+=v; k->sum1=k->sum*log(L); return; } int mid=L+R>>1; if(x<=mid) Insert(x,v,k->ls,L,mid); else Insert(x,v,k->rs,mid+1,R); k->maintain();}int Query(int x,int y,Node *&k){ if(k==null) return 0; if(k->l>=x && k->r<=y){ int t=k->sum; k=null; return t; } int mid=k->l+k->r>>1,t; if(mid>=y) t=Query(x,y,k->ls); else if(mid<x) t=Query(x,y,k->rs); else t=Query(x,y,k->ls)+Query(x,y,k->rs); if(k->l>=x && k->r<=y) k=null; k->maintain(); return t;}int K_th(int x,Node *k){ if(k->l==k->r) return k->l; if(k->ls->sum>=x) return K_th(x,k->ls); return K_th(x-k->ls->sum,k->rs);///求第k大类似于平衡树}void Debug(Node *x){///调试orz.... if(x->ls!=null) Debug(x->ls); if(x->rs!=null) Debug(x->rs); printf("%d %d %d %lf\n",x->l,x->r,x->sum,x->sum1);}int main(){ null=new Node(0,0); null->ls=null->rs=null; null->sum=null->sum1=0; n=read(); for(int i=1;i<=n;i++){ t=read(); switch(t){ case 1: x=read(); Insert(x,1,(root[++top]=new Node(1,INF)),1,INF); f[top]=top; break; case 2: x=Find(read()); y=Find(read()); if(x!=y) Merge(root[x],root[y]); f[y]=x; break; case 3: x=Find(read()); y=read(); k=Query(1,y-1,root[x]); Insert(y,k,root[x],1,INF); break; case 4: x=Find(read()); y=read(); k=Query(y+1,INF,root[x]); Insert(y,k,root[x],1,INF); break; case 5: x=Find(read()); y=read(); printf("%d\n",K_th(y,root[x])); break; case 6: x=Find(read()); y=Find(read()); puts(root[x]->sum1>root[y]->sum1?"1":"0"); break; case 7: x=Find(read()); printf("%d\n",root[x]->sum); break; } }return 0;}
阅读全文
0 0
- [线段树 合并] BZOJ 4399 魔法少女LJJ
- BZOJ 4399 魔法少女LJJ 线段树合并
- 【bzoj 4399】魔法少女LJJ(线段树合并)
- BZOJ[4399]魔法少女LJJ 线段树合并
- 【线段树合并】【bzoj4399】: 魔法少女LJJ
- BZOJ 4399: 魔法少女LJJ
- 4399: 魔法少女LJJ
- bzoj 4399 魔法少女 权值线段树合并+并查集
- BZOJ4399: 魔法少女LJJ
- BZOJ4399: 魔法少女LJJ treap
- BZOJ 3123 线段树合并
- 魔法少女
- 魔法少女
- 魔法少女
- 魔法少女
- bzoj 3702: 二叉树 线段树合并
- [线段树合并] BZOJ 2733 永无乡
- BZOJ 2212线段树的合并
- linux进程状态详解
- 快来庆祝我的博客开通吧
- 利用高德地图实现定位功能
- 留言本问题总结
- reeds-shepp曲线
- BZOJ[4399]魔法少女LJJ 线段树合并
- Linux应用内存泄露分析与定位
- 岩小松:WIN10系统怎么校准电脑系统时间
- 从NIPS 2017看AI未来:黄仁勋等提出新方向:机器人不尬聊、AI可学习并预测人类行为
- 用python绘制气温图,并着色
- 区分几个概念
- 织梦5.7的一些小修改
- java中ajax的用法
- 《20171124》