热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

树套树——BZOJ3196/Luogu3380二逼平衡树

http://www.lydsy.com/JudgeOnline/problem.php?id=3196 https://www.luogu.org/problem/show?pid&#61

http://www.lydsy.com/JudgeOnline/problem.php?id=3196
https://www.luogu.org/problem/show?pid=3380
tyvj原题:传送门
这么多乱七八糟的操作,交给平衡树好了
再加上区间,外面套个线段树好了
不过呢,可能我写得太渣了吧,splay一直TLE
没办法,换了个非旋式Treap搞搞掉算了。。。

#include
using namespace std;
const int oo=2147483647;
struct tree{int l,r,v,w,s,nod;
}t[2000001];
int a[200001],root[200001];
int sum=0,n,m,ans;
inline void update(int x){t[x].s=t[t[x].l].s+t[t[x].r].s+t[x].w;}
inline void rturn(int &x){int tt=t[x].l;t[x].l=t[tt].r;t[tt].r=x;t[tt].s=t[x].s;update(x);x=tt;
}
inline void lturn(int &x){int tt=t[x].r;t[x].r=t[tt].l;t[tt].l=x;t[tt].s=t[x].s;update(x);x=tt;
}
inline void sinsert(int &x,int y){if(x==0){sum++;x=sum;t[x].s=t[x].w=1;t[x].v=y;t[x].nod=rand();return;}t[x].s++;if(t[x].v==y)t[x].w++;else if(y>t[x].v){sinsert(t[x].r,y);if(t[t[x].r].nodelse{sinsert(t[x].l,y);if(t[t[x].l].nod}
inline void sshan(int &x,int y){if(x==0)return;if(t[x].v==y){if(t[x].w>1){t[x].w--;t[x].s--;return;}if(t[x].l*t[x].r==0)x=t[x].l+t[x].r;else if(t[t[x].l].nodelse lturn(x),sshan(x,y);}else if(y>t[x].v)t[x].s--,sshan(t[x].r,y);else t[x].s--,sshan(t[x].l,y);
}
inline void srank(int x,int y){if(x==0)return;if(t[x].v==y){ans+=t[t[x].l].s;return;}else if(y>t[x].v){ans+=t[t[x].l].s+t[x].w;srank(t[x].r,y);}else srank(t[x].l,y);
}
inline void spre(int x,int y){if(x==0)return;if(t[x].velse spre(t[x].l,y);
}
inline void ssucc(int x,int y){if(x==0)return;if(t[x].v>y){ans=min(ans,t[x].v);ssucc(t[x].l,y);}else ssucc(t[x].r,y);
}
inline void winsert(int l,int r,int x,int v,int nod){sinsert(root[nod],v);if(l&#61;&#61;r)return;int mid&#61;(l&#43;r)>>1;if(x<&#61;mid)winsert(l,mid,x,v,nod*2);else winsert(mid&#43;1,r,x,v,nod*2&#43;1);
}
inline void wrank(int l,int r,int x,int y,int k,int nod){if(l&#61;&#61;x&&r&#61;&#61;y){srank(root[nod],k);return;}int mid&#61;(l&#43;r)>>1;if(mid>&#61;y)wrank(l,mid,x,y,k,nod*2);else if(x>mid)wrank(mid&#43;1,r,x,y,k,nod*2&#43;1);else{wrank(l,mid,x,mid,k,nod*2);wrank(mid&#43;1,r,mid&#43;1,y,k,nod*2&#43;1);}
}
inline int wnum(int x,int y,int k){int l&#61;0,r&#61;oo,cnt;while(l<&#61;r){ans&#61;1;int mid&#61;(l&#43;r)>>1;wrank(1,n,x,y,mid,1);if(ans<&#61;k)cnt&#61;mid,l&#61;mid&#43;1;else r&#61;mid-1;}return cnt;
}
inline void whuan(int l,int r,int x,int y,int v,int nod){sshan(root[nod],y);sinsert(root[nod],v);if(l&#61;&#61;r)return;int mid&#61;(l&#43;r)>>1;if(x<&#61;mid)whuan(l,mid,x,y,v,nod*2);else whuan(mid&#43;1,r,x,y,v,nod*2&#43;1);
}
inline void wpre(int l,int r,int x,int y,int k,int nod){if(l&#61;&#61;x&&r&#61;&#61;y){spre(root[nod],k);return;}int mid&#61;(l&#43;r)>>1;if(mid>&#61;y)wpre(l,mid,x,y,k,nod*2);else if(x>mid)wpre(mid&#43;1,r,x,y,k,nod*2&#43;1);else{wpre(l,mid,x,mid,k,nod*2);wpre(mid&#43;1,r,mid&#43;1,y,k,nod*2&#43;1);}
}
inline void wsucc(int l,int r,int x,int y,int k,int nod){if(l&#61;&#61;x&&r&#61;&#61;y){ssucc(root[nod],k);return;}int mid&#61;(l&#43;r)>>1;if(mid>&#61;y)wsucc(l,mid,x,y,k,nod*2);else if(x>mid)wsucc(mid&#43;1,r,x,y,k,nod*2&#43;1);else{wsucc(l,mid,x,mid,k,nod*2);wsucc(mid&#43;1,r,mid&#43;1,y,k,nod*2&#43;1);}
}
int main()
{scanf("%d%d",&n,&m);for(int i&#61;1;i<&#61;n;i&#43;&#43;){scanf("%d",&a[i]);winsert(1,n,i,a[i],1);}int x,y,z,k;for(int i&#61;1;i<&#61;m;i&#43;&#43;){scanf("%d%d%d",&z,&x,&y);if(z&#61;&#61;1)scanf("%d",&k),ans&#61;1,wrank(1,n,x,y,k,1),printf("%d\n",ans);else if(z&#61;&#61;2)scanf("%d",&k),printf("%d\n",wnum(x,y,k));else if(z&#61;&#61;3)whuan(1,n,x,a[x],y,1),a[x]&#61;y;else if(z&#61;&#61;4)scanf("%d",&k),ans&#61;-oo,wpre(1,n,x,y,k,1),printf("%d\n",ans);else if(z&#61;&#61;5)scanf("%d",&k),ans&#61;oo,wsucc(1,n,x,y,k,1),printf("%d\n",ans);}return 0;
}

贴一下我的splay代码吧&#xff0c;欢迎大佬帮我找错&#xff0c;谢谢辣>_<&#xff01;

#include
using namespace std;
const int oo&#61;2147483647;
int t[2000001][2],fa[2000001],v[2000001],val[2000001],s[2000001];
int a[200001],root[200001];
int tt&#61;0,n,m,ans;
inline void pushup(int x){s[x]&#61;s[t[x][0]]&#43;s[t[x][1]]&#43;v[x];}
inline void turn(int x,int &p){int y&#61;fa[x],z&#61;fa[y],l,r;if(t[y][0]&#61;&#61;x)l&#61;0;else l&#61;1;r&#61;l^1;if(y&#61;&#61;p)p&#61;x;else if(t[z][0]&#61;&#61;y)t[z][0]&#61;x;else t[z][1]&#61;x;fa[x]&#61;z;fa[y]&#61;x;fa[t[x][r]]&#61;y;t[y][l]&#61;t[x][r];t[x][r]&#61;y;pushup(y);pushup(x);
}
inline void splay(int x,int &p){int y,z;while(x!&#61;p){y&#61;fa[x];z&#61;fa[y];if(y!&#61;p){if((t[y][0]&#61;&#61;x)^(t[z][0]&#61;&#61;y))turn(x,p);else turn(y,p);}turn(x,p);}
}
inline void sinsert(int& rt,int k){if(!rt){tt&#43;&#43;;rt&#61;tt;val[tt]&#61;k;s[tt]&#61;v[tt]&#61;1;return;}int p&#61;rt,z;while(p){z&#61;p;s[p]&#43;&#43;;if(k0];else if(k>val[p])p&#61;t[p][1];else{v[p]&#43;&#43;;pushup(p);splay(p,rt);return;}}if(val[z]>k)t[z][0]&#61;&#43;&#43;tt;else t[z][1]&#61;&#43;&#43;tt;val[tt]&#61;k;s[tt]&#61;v[tt]&#61;1;fa[tt]&#61;z;splay(tt,rt);
}
inline void sshan(int& rt,int y){int x&#61;rt;while(val[x]!&#61;y){if(val[x]>y)x&#61;t[x][0];else x&#61;t[x][1];}splay(x,rt);if(v[x]>1){v[x]--;pushup(x);return;}if(t[x][0]*t[x][1]&#61;&#61;0)rt&#61;t[x][0]&#43;t[x][1];else{int y&#61;t[x][1];while(t[y][0])y&#61;t[y][0];t[y][0]&#61;t[x][0];fa[t[x][0]]&#61;y;s[t[y][0]]&#61;s[t[x][0]];v[t[y][0]]&#61;v[t[x][0]];pushup(y);rt&#61;t[x][1];}fa[rt]&#61;0;
}
inline void srank(int x,int y){if(x&#61;&#61;0)return;if(val[x]&#61;&#61;y){ans&#43;&#61;s[t[x][0]];return;}else if(y>val[x]){ans&#43;&#61;s[t[x][0]]&#43;v[x];srank(t[x][1],y);}else srank(t[x][0],y);
}
inline void spre(int x,int y){if(x&#61;&#61;0)return;if(val[x]1],y);}else spre(t[x][0],y);
}
inline void ssucc(int x,int y){if(x&#61;&#61;0)return;if(val[x]>y){ans&#61;min(ans,val[x]);ssucc(t[x][0],y);}else ssucc(t[x][1],y);
}
inline void winsert(int l,int r,int x,int v,int nod){sinsert(root[nod],v);if(l&#61;&#61;r)return;int mid&#61;(l&#43;r)>>1;if(x<&#61;mid)winsert(l,mid,x,v,nod*2);else winsert(mid&#43;1,r,x,v,nod*2&#43;1);
}
inline void wrank(int l,int r,int x,int y,int k,int nod){if(l&#61;&#61;x&&r&#61;&#61;y){srank(root[nod],k);return;}int mid&#61;(l&#43;r)>>1;if(mid>&#61;y)wrank(l,mid,x,y,k,nod*2);else if(x>mid)wrank(mid&#43;1,r,x,y,k,nod*2&#43;1);else{wrank(l,mid,x,mid,k,nod*2);wrank(mid&#43;1,r,mid&#43;1,y,k,nod*2&#43;1);}
}
inline void wnum(int x,int y,int k){int l&#61;0,r&#61;oo,cnt;while(l<&#61;r){ans&#61;1;int mid&#61;(l&#43;r)>>1;wrank(1,n,x,y,mid,1);if(ans<&#61;k)cnt&#61;mid,l&#61;mid&#43;1;else r&#61;mid-1;}return cnt;
}
inline void whuan(int l,int r,int x,int y,int v,int nod){sshan(root[nod],y);sinsert(root[nod],v);if(l&#61;&#61;r)return;int mid&#61;(l&#43;r)>>1;if(x<&#61;mid)whuan(l,mid,x,y,v,nod*2);else whuan(mid&#43;1,r,x,y,v,nod*2&#43;1);
}
inline void wpre(int l,int r,int x,int y,int k,int nod){if(l&#61;&#61;x&&r&#61;&#61;y){spre(root[nod],k);return;}int mid&#61;(l&#43;r)>>1;if(mid>&#61;y)wpre(l,mid,x,y,k,nod*2);else if(x>mid)wpre(mid&#43;1,r,x,y,k,nod*2&#43;1);else{wpre(l,mid,x,mid,k,nod*2);wpre(mid&#43;1,r,mid&#43;1,y,k,nod*2&#43;1);}
}
inline void wsucc(int l,int r,int x,int y,int k,int nod){if(l&#61;&#61;x&&r&#61;&#61;y){ssucc(root[nod],k);return;}int mid&#61;(l&#43;r)>>1;if(mid>&#61;y)wsucc(l,mid,x,y,k,nod*2);else if(x>mid)wsucc(mid&#43;1,r,x,y,k,nod*2&#43;1);else{wsucc(l,mid,x,mid,k,nod*2);wsucc(mid&#43;1,r,mid&#43;1,y,k,nod*2&#43;1);}
}
int main()
{scanf("%d%d",&n,&m);for(int i&#61;1;i<&#61;n;i&#43;&#43;){scanf("%d",&a[i]);winsert(1,n,i,a[i],1);}int x,y,z,k;for(int i&#61;1;i<&#61;m;i&#43;&#43;){scanf("%d%d%d",&z,&x,&y);if(z&#61;&#61;1)scanf("%d",&k),ans&#61;1,wrank(1,n,x,y,k,1),printf("%d\n",ans);else if(z&#61;&#61;2)scanf("%d",&k),printf("%d\n",wnum(x,y,k));else if(z&#61;&#61;3)whuan(1,n,x,a[x],y,1),a[x]&#61;y;else if(z&#61;&#61;4)scanf("%d",&k),ans&#61;-oo,wpre(1,n,x,y,k,1),printf("%d\n",ans);else if(z&#61;&#61;5)scanf("%d",&k),ans&#61;oo,wsucc(1,n,x,y,k,1),printf("%d\n",ans);}return 0;
}


推荐阅读
  • 本文介绍了一道经典的状态压缩题目——关灯问题2,并提供了解决该问题的算法思路。通过使用二进制表示灯的状态,并枚举所有可能的状态,可以求解出最少按按钮的次数,从而将所有灯关掉。本文还对状压和位运算进行了解释,并指出了该方法的适用性和局限性。 ... [详细]
  • 本文介绍了Codeforces Round #321 (Div. 2)比赛中的问题Kefa and Dishes,通过状压和spfa算法解决了这个问题。给定一个有向图,求在不超过m步的情况下,能获得的最大权值和。点不能重复走。文章详细介绍了问题的题意、解题思路和代码实现。 ... [详细]
  • 本文为Codeforces 1294A题目的解析,主要讨论了Collecting Coins整除+不整除问题。文章详细介绍了题目的背景和要求,并给出了解题思路和代码实现。同时提供了在线测评地址和相关参考链接。 ... [详细]
  • 本文介绍了C++中省略号类型和参数个数不确定函数参数的使用方法,并提供了一个范例。通过宏定义的方式,可以方便地处理不定参数的情况。文章中给出了具体的代码实现,并对代码进行了解释和说明。这对于需要处理不定参数的情况的程序员来说,是一个很有用的参考资料。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 本文介绍了P1651题目的描述和要求,以及计算能搭建的塔的最大高度的方法。通过动态规划和状压技术,将问题转化为求解差值的问题,并定义了相应的状态。最终得出了计算最大高度的解法。 ... [详细]
  • 本文介绍了解决二叉树层序创建问题的方法。通过使用队列结构体和二叉树结构体,实现了入队和出队操作,并提供了判断队列是否为空的函数。详细介绍了解决该问题的步骤和流程。 ... [详细]
  • HDFS2.x新特性
    一、集群间数据拷贝scp实现两个远程主机之间的文件复制scp-rhello.txtroothadoop103:useratguiguhello.txt推pushscp-rr ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • Go语言实现堆排序的详细教程
    本文主要介绍了Go语言实现堆排序的详细教程,包括大根堆的定义和完全二叉树的概念。通过图解和算法描述,详细介绍了堆排序的实现过程。堆排序是一种效率很高的排序算法,时间复杂度为O(nlgn)。阅读本文大约需要15分钟。 ... [详细]
  • 李逍遥寻找仙药的迷阵之旅
    本文讲述了少年李逍遥为了救治婶婶的病情,前往仙灵岛寻找仙药的故事。他需要穿越一个由M×N个方格组成的迷阵,有些方格内有怪物,有些方格是安全的。李逍遥需要避开有怪物的方格,并经过最少的方格,找到仙药。在寻找的过程中,他还会遇到神秘人物。本文提供了一个迷阵样例及李逍遥找到仙药的路线。 ... [详细]
  • 先看官方文档TheJavaTutorialshavebeenwrittenforJDK8.Examplesandpracticesdescribedinthispagedontta ... [详细]
  • 海马s5近光灯能否直接更换为H7?
    本文主要介绍了海马s5车型的近光灯是否可以直接更换为H7灯泡,并提供了完整的教程下载地址。此外,还详细讲解了DSP功能函数中的数据拷贝、数据填充和浮点数转换为定点数的相关内容。 ... [详细]
  • 本文介绍了使用哈夫曼树实现文件压缩和解压的方法。首先对数据结构课程设计中的代码进行了分析,包括使用时间调用、常量定义和统计文件中各个字符时相关的结构体。然后讨论了哈夫曼树的实现原理和算法。最后介绍了文件压缩和解压的具体步骤,包括字符统计、构建哈夫曼树、生成编码表、编码和解码过程。通过实例演示了文件压缩和解压的效果。本文的内容对于理解哈夫曼树的实现原理和应用具有一定的参考价值。 ... [详细]
  • 本文介绍了一种轻巧方便的工具——集算器,通过使用集算器可以将文本日志变成结构化数据,然后可以使用SQL式查询。集算器利用集算语言的优点,将日志内容结构化为数据表结构,SPL支持直接对结构化的文件进行SQL查询,不再需要安装配置第三方数据库软件。本文还详细介绍了具体的实施过程。 ... [详细]
author-avatar
天佑忍者忍着
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有