题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3196

人生中第一棵树套树!

写了一个晚上,成功卡时 9000ms+ 过了!

很要注意数组的大小,因为是树*树的大小嘛!

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int const maxn=2e6+5,nn=5e4+5,inf=1e9;//2e6!!
int n,m,tot,siz[maxn],c[maxn][3],fa[maxn],key[maxn],mn,mx,a[nn];
struct N{int l,r,rt;
}t[nn<<2];
void update(int x){siz[x]=siz[c[x][0]]+siz[c[x][1]]+1;}
void rotate(int x)
{int y=fa[x],z=fa[y],d=(c[y][1]==x);if(z!=0)c[z][c[z][1]==y]=x;fa[x]=z; fa[y]=x; fa[c[x][d^1]]=y;c[y][d]=c[x][d^1]; c[x][d^1]=y; update(y); update(x);
}
void splay(int x,int f)//fa[x]=f
{while(fa[x]!=f){int y=fa[x],z=fa[y];if(z!=f)// z 而非 y
        {if((c[y][1]==x)^(c[z][1]==y)) rotate(x);else rotate(y);}rotate(x);}
}
int find_pre(int x,int v)
{if(!x)return 0;if(key[x]>=v) return find_pre(c[x][0],v);else{int y=find_pre(c[x][1],v);if(y)return y; else return x;}
}
int find_k(int x,int k)
{
//    if(!x)return 0;if(siz[c[x][0]]==k-1)return x;if(siz[c[x][0]]>k-1)return find_k(c[x][0],k);return find_k(c[x][1],k-siz[c[x][0]]-1);
}
int find_suc(int x,int k)//后继
{if(!x)return 0;if(key[x]<=k)return find_suc(c[x][1],k);else{int y=find_suc(c[x][0],k);if(y)return y; else return x;//说不定就是 x
    }
}
int find_Suc(int x,int k)//相等中最小的
{if(!x)return 0;if(key[x]<k)return find_Suc(c[x][1],k);else{int y=find_Suc(c[x][0],k);if(y)return y; else return x;//说不定就是 x
    }
}
int query_k(int &x,int k)//查询 k 的排名
{int p=find_Suc(x,k); splay(p,0);//相等中最小的x=p;return siz[c[p][0]]-1;// -inf
}
int query(int &x,int k)//二分用
{int p=find_suc(x,k); splay(p,0);x=p;return siz[c[p][0]]-1;// -inf
}
void insert(int &x,int v)
{int p=find_pre(x,v); splay(p,0);int y=find_k(c[p][1],1); splay(y,p);//ptot++; siz[tot]=1; fa[tot]=y; key[tot]=v; c[y][0]=tot;update(y); update(p);x=p;//rt
}
void del(int &x,int v)
{int p=find_pre(x,v); splay(p,0);int y=find_k(c[p][1],2); splay(y,p);//pfa[c[y][0]]=0; c[y][0]=0;update(y); update(p);x=p;
}
void build(int x,int l,int r)
{t[x].l=l; t[x].r=r;t[x].rt=++tot; siz[tot]=2; fa[tot]=0; c[tot][1]=tot+1; key[tot]=-inf;tot++; siz[tot]=1; fa[tot]=tot-1; key[tot]=inf;for(int i=l;i<=r;i++)insert(t[x].rt,a[i]);if(l==r)return;int mid=(l+r)>>1;build(x<<1,l,mid); build(x<<1|1,mid+1,r);
}
int query_k(int x,int l,int r,int k)//查询 k 的排名
{if(t[x].l>=l && t[x].r<=r)return query_k(t[x].rt,k);//<=k 的个数 int mid=(t[x].l+t[x].r)>>1,ret=0;//不是 l,r if(mid>=l)ret+=query_k(x<<1,l,r,k);//l,r,无需 l,mid ,因为自带 t[x].l,t[x].r if(mid<r)ret+=query_k(x<<1|1,l,r,k);return ret;
}
int query(int x,int l,int r,int k)//二分用 //<=mid的个数
{if(t[x].l>=l && t[x].r<=r)return query(t[x].rt,k);int mid=(t[x].l+t[x].r)>>1,ret=0;//不是 l,r if(mid>=l)ret+=query(x<<1,l,r,k);if(mid<r)ret+=query(x<<1|1,l,r,k);return ret;
}
void modify(int x,int p,int k)
{insert(t[x].rt,k); del(t[x].rt,a[p]); if(t[x].l==t[x].r)return;//
    int mid=(t[x].l+t[x].r)>>1;if(p<=mid)modify(x<<1,p,k);else modify(x<<1|1,p,k);
}
int query_pre(int x,int l,int r,int k)
{if(t[x].l>=l && t[x].r<=r)return key[find_pre(t[x].rt,k)];//返回 key ,因为需要比较int mid=(t[x].l+t[x].r)>>1,ret=0;if(mid>=l)ret=max(ret,query_pre(x<<1,l,r,k));if(mid<r)ret=max(ret,query_pre(x<<1|1,l,r,k)); return ret;
}
int query_suc(int x,int l,int r,int k)
{if(t[x].l>=l && t[x].r<=r)return key[find_suc(t[x].rt,k)];//返回 key ,因为需要比较int mid=(t[x].l+t[x].r)>>1,ret=inf;if(mid>=l)ret=min(ret,query_suc(x<<1,l,r,k));if(mid<r)ret=min(ret,query_suc(x<<1|1,l,r,k)); return ret;
}
int main()
{scanf("%d%d",&n,&m);for(int i=1;i<=n;i++){scanf("%d",&a[i]);mn=min(mn,a[i]); mx=max(mx,a[i]);}build(1,1,n);for(int i=1,op,l,r,k;i<=m;i++){scanf("%d",&op);if(op!=3)scanf("%d%d%d",&l,&r,&k);if(op==1)printf("%d\n",query_k(1,l,r,k)+1);//+1if(op==2){int L=mn,R=mx,ans=0;while(L<=R){int mid=(L+R)>>1;if(query(1,l,r,mid)>=k)ans=mid,R=mid-1;// >也可,因为查询的是 <=mid 的个数 else L=mid+1;}printf("%d\n",ans);}if(op==3){int pos; scanf("%d%d",&pos,&k);modify(1,pos,k);a[pos]=k;//!!!
        }if(op==4)printf("%d\n",query_pre(1,l,r,k));if(op==5)printf("%d\n",query_suc(1,l,r,k));}return 0;
}

转载于:https://www.cnblogs.com/Zinn/p/9221949.html

bzoj3196 二逼平衡树——线段树套平衡树相关推荐

  1. 【BZOJ-3196】二逼平衡树 线段树 + Splay (线段树套平衡树)

    3196: Tyvj 1730 二逼平衡树 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 2271  Solved: 935 [Submit][St ...

  2. 树套树-线段树套平衡树

    作用 线段树的作用是区间修改和查询,平衡树的作用是查询第k大,k的排名,前驱,后继.这两个结合起来,就变成了可以区间修改和查询第k大,k的排名,前驱,后继的数据结构:树套树-线段树套平衡树. 实现 先 ...

  3. 并不对劲的线段树套平衡树

    最近很对劲的太刀流做的一道题中说树是无向连通无环图,并不对劲的片手流为了反驳他,决定与之针锋相对,就练线段无向连通无环图套平衡无向连通无环图的题. 很对劲的太刀流-> 题意非常简单,就是维护一个 ...

  4. 二逼平横树——线段树套平衡树

    注意空间大小,以及建树时的细节 #include<cstdio> #include<algorithm> #include<iostream> using name ...

  5. BZOJ3196 二逼平衡树 ZKW线段树套vector(滑稽)

    我实在是不想再打一遍树状数组套替罪羊树了... 然后在普通平衡树瞎逛的时候找到了以前看过vector题解 于是我想:为啥不把平衡树换成vector呢??? 然后我又去学了一下ZKW线段树 就用ZKW线 ...

  6. 洛谷 P3380 bzoj3196 Tyvj1730 【模板】二逼平衡树(树套树)

    [模板]二逼平衡树(树套树) 题目描述 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 查询k在区间内的排名 查询区间内排名为k的值 修改某一位值上的数值 查询k在 ...

  7. 二逼平衡树——树套树(线段树套Splay平衡树)

    题面 Bzoj3196 解析 线段树和Splay两棵树套在一起,常数直逼inf,但最终侥幸过了 思路还是比较简单, 在原数组维护一个下标线段树,再在每一个线段树节点,维护一个对应区间的权值Splay. ...

  8. 二逼平衡树 题解(树套树)

    题面 我 想 扇 死 自 己 void up(int x){if(x){size[x]=cnt[x];//我TM这行忘了if(son[x][0])size[x]+=size[son[x][0]];if ...

  9. 模板:二维线段树(线段树套线段树)

    文章目录 问题 解析 单点修改 询问 完整代码 标记永久化 代码 所谓二维线段树,就是有两个维度的线段树 (逃) 问题 给出一个矩形 要求支持以下操作: 1.询问一个子矩形的最值 2.修改某一个单点的 ...

  10. 【Luogu】P3380树套树模板(线段树套Splay)

    题目链接 幸甚至哉,歌以咏志. 拿下了曾经是那么遥不可及的线段树,学会了曾经高不可攀的平衡树,弄懂了装B的时候才挂在嘴边的树套树. 每道模板都是链上的一颗珠子.把它们挨个串起来,就成为我成长的历程. ...

最新文章

  1. 解决 json_encode 中文乱码
  2. android 始终显示overflow菜单
  3. 【Python】一文搞懂Pandas数据排序
  4. 我的电脑不联网,很安全,黑客:你还有风扇呢。。。
  5. CV与IP:基础,经典以及最近发展
  6. linux之tar命令使用总结
  7. fasync驱动异步通知机制
  8. 攻防世界web新手区解题 view_source / robots / backup
  9. SolarWinds 供应链攻击中的第四款恶意软件及其它动态
  10. 内部曝料——博文年会之《武林外传》
  11. 力扣 69. x 的平方根 三种方法
  12. C++实现简单钢琴(文件读取 - 播放曲谱)
  13. 白化滤波器matlab程序,04实验四:白化滤波器的设计实验报告
  14. 维和医疗分队患者信息管理系统的开发与研究
  15. 专访OKEX Jay Hao:期权市场的需求从何而来?
  16. 通过瑞利判据对显微镜物镜进行分辨率研究
  17. SPSS结果解读——【独立样本T检验】【方差齐性】
  18. java程序设计高级教程答案_Java高级程序设计实战教程答案
  19. ES5-ES6-ES7_字符串与JOSN格式的数据相互转换以及深度克隆新对象
  20. IT行业都有哪些岗位?

热门文章

  1. poj 1797 Heavy Transportation 本来以为floyd瞬秒,结果各种re,真无语,看网上别人的并查集了
  2. 苹果Mac文件夹样式设计工具:Folder Designer
  3. 如何将 Mac 置入睡眠状态或唤醒 Mac?
  4. iOS开发之实现方法链调用
  5. Mac上功能强大图片查看编辑工具:zGallery
  6. Jump Desktop for Mac(远程桌面控制工具)怎么链接windows电脑
  7. 三数之和,去除重复。
  8. 系统时间正常日志时间不正常
  9. Android Messenger 跨进程通信
  10. 【红顶商人胡雪岩】-- 读完一点小感