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

主席树学习

 很好的博客:https:blog.csdn.netqq_39809664articledetails79934516可持久化数组#include#inclu

 

很好的博客:https://blog.csdn.net/qq_39809664/article/details/79934516


可持久化数组

#include
#include
#include
#include
#include
#include
#include
#define ll long long
using namespace std;
const int maxn=1000000+10101;
inline int read(){
int x=0,f=1;char ch=getchar();
for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
for(;isdigit(ch);ch=getchar())x=(x<<3)+(x<<1)+ch-'0';
return x*f;
}
int n,m,a[maxn],tree[maxn*20],rt[maxn*20],cnt,lc[maxn*20],rc[maxn*20];
//rt[i]为插入i个点后的树的根节点编号
void build(int &k,int l,int r){
k=++cnt;
if(l==r){tree[k]=a[l];return ;}
int mid=l+r>>1;
build(lc[k],l,mid);build(rc[k],mid+1,r);
return ;
}
void change(int &k,int pre,int l,int r,int q,int v){
k=++cnt;lc[k]=lc[pre];rc[k]=rc[pre];tree[k]=tree[pre];
if(l==r){tree[k]=v;return ;}
int mid=l+r>>1;
if(mid else change(lc[k],lc[pre],l,mid,q,v);
}
int query(int k,int l,int r,int pos){
if(l==r)return tree[k];
int mid=l+r>>1;
if(pos<=mid)return query(lc[k],l,mid,pos);
else return query(rc[k],mid+1,r,pos);
}
int main(){
n=read();m=read();
for(int i=1;i<=n;i++)a[i]=read();
build(rt[0],1,n);
for(int i=1;i<=m;i++){
int vi=read(),opt=read(),x=read();
if(opt==1)change(rt[i],rt[vi],1,n,x,read());
else printf("%d\n",query(rt[vi],1,n,x)),rt[i]=rt[vi];
}
return 0;
}

 


可持久化线段树 1(主席树)

#include
#include
#include
#include
#include
#include
#include
#define ll long long
using namespace std;
const int maxn=1000000+10101;
inline int read(){
int x=0,f=1;char ch=getchar();
for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
for(;isdigit(ch);ch=getchar())x=(x<<3)+(x<<1)+ch-'0';
return x*f;
}
int len,n,m,a[maxn],b[maxn],cnt,rt[maxn*20];
struct wzq{
int sum,lr,rc;
}tre[maxn*20];
void build(int &k,int l,int r){
k=++cnt;
if(l==r)return ;
int mid=l+r>>1;
build(tre[k].lr,l,mid);build(tre[k].rc,mid+1,r);
return ;
}
void update(int l,int r,int &now,int pre,int pos){
tre[++cnt]=tre[pre];
now=cnt;
tre[cnt].sum++;
if(l==r)return ;
int mid=l+r>>1;
if(pos<=mid)update(l,mid,tre[now].lr,tre[pre].lr,pos);
else update(mid+1,r,tre[now].rc,tre[pre].rc,pos);
return ;
}
int query(int l,int r,int x,int y,int pos){
if(l==r)return l;
int xx=tre[tre[y].lr].sum-tre[tre[x].lr].sum;
int mid=l+r>>1;
if(xx>=pos)return query(l,mid,tre[x].lr,tre[y].lr,pos);
return query(mid+1,r,tre[x].rc,tre[y].rc,pos-xx);
}
int main(){
n=read();m=read();
for(int i=1;i<=n;i++)a[i]=read(),b[i]=a[i];
sort(a+1,a+n+1);
len=unique(a+1,a+1+n)-a-1;
build(rt[0],1,m);
for(int i=1;i<=n;i++){
int t=lower_bound(a+1,a+1+m,b[i])-a;
update(1,m,rt[i],rt[i-1],t);
}
for(int i=1;i<=m;i++){
int l=read(),r=read(),k=read();
printf("%d\n",a[query(1,m,rt[l-1],rt[r],k)]);
}
return 0;
}

 


[CQOI2015]任务查询系统

这道题可以对每秒建棵权值线段树,并以1~lim(优先级的最大值)为区间大小记录个数,这样就可以处理在x秒的第k小前缀和了,

但是lim因为很大,可能会导致MLE,所以要离散化一下

// luogu-judger-enable-o2
#include
#include
#include
#include
#include
#include
#include
#define ll long long
using namespace std;
const int maxn=201010;
inline int read(){
int x=0,f=1;char ch=getchar();
for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
for(;isdigit(ch);ch=getchar())x=(x<<3)+(x<<1)+ch-'0';
return x*f;
}
int n,m,cnt,tot,rt[maxn],to[maxn],h[maxn];
ll ans=1;
struct wzq{ll sum;int sz,lr,rc;}tre[maxn*128];
struct hhh{int pos,v;}b[maxn];
bool cmp(hhh i,hhh j){return i.posvoid build(int &k,int l,int r){
k=++cnt;
if(l==r)return ;
int mid=l+r>>1;
build(tre[k].lr,l,mid);build(tre[k].rc,mid+1,r);
return ;
}
void change(int &k,int pre,int l,int r,int tag){
k=++cnt;
tre[k]=tre[pre];tre[k].sum+=tag;
if(tag<0)tre[k].sz--;
else tre[k].sz++;
if(l==r)return ;
int mid=l+r>>1;
if(abs(tag)<=h[mid])change(tre[k].lr,tre[pre].lr,l,mid,tag);
else change(tre[k].rc,tre[pre].rc,mid+1,r,tag);
return ;
}
ll query(int k,int l,int r,int pos){
if(l==r)return 1ll*tre[k].sum/tre[k].sz*min(pos,tre[k].sz);
int mid=l+r>>1;
if(tre[tre[k].lr].sz>=pos)return 1ll*query(tre[k].lr,l,mid,pos);
return 1ll*tre[tre[k].lr].sum+query(tre[k].rc,mid+1,r,pos-tre[tre[k].lr].sz);
}
int main(){
m=read();n=read();
for(int i=1;i<=m;i++){
int x=read(),y=read(),z=read();
b[++tot].pos=x;b[tot].v=z;
b[++tot].pos=y+1;b[tot].v=-z;
h[i]=z;
}
sort(h+1,h+m+1);
int tot1=unique(h+1,h+m+1)-h-1;
sort(b+1,b+tot+1,cmp);build(rt[0],1,tot1);
for(int i=1;i<=tot;i++)change(rt[i],rt[i-1],1,tot1,b[i].v);
for(int i=tot;i>=1;i--)if(b[i].pos!=b[i+1].pos)to[b[i].pos]=i;
for(int i=1;i<=m;i++)if(!to[i])to[i]=to[i-1];
for(int i=1;i<=n;i++){
ll x=read(),a=read(),b=read(),c=read();
ll k=(1ll*a*ans+b)%c+1;
x=rt[to[x]];
if(tre[x].sz<=k)ans=1ll*tre[x].sum;
else ans=query(x,1,tot1,k);
printf("%lld\n",ans);
}
return 0;
}

 


推荐阅读
  • 在高并发需求的C++项目中,我们最初选择了JsonCpp进行JSON解析和序列化。然而,在处理大数据量时,JsonCpp频繁抛出异常,尤其是在多线程环境下问题更为突出。通过分析发现,旧版本的JsonCpp存在多线程安全性和性能瓶颈。经过评估,我们最终选择了RapidJSON作为替代方案,并实现了显著的性能提升。 ... [详细]
  • 本文介绍如何从字符串中移除大写、小写、特殊、数字和非数字字符,并提供了多种编程语言的实现示例。 ... [详细]
  • 主调|大侠_重温C++ ... [详细]
  • Linux环境下C语言实现定时向文件写入当前时间
    本文介绍如何在Linux系统中使用C语言编程,实现在每秒钟向指定文件中写入当前时间戳。通过此示例,读者可以了解基本的文件操作、时间处理以及循环控制。 ... [详细]
  • 本文详细解释了为什么在成功执行移动赋值操作后,对象的析构函数会被调用,并提供了代码示例和详细的分析。 ... [详细]
  • CSS高级技巧:动态高亮当前页面导航
    本文介绍了如何使用CSS实现网站导航栏中当前页面的高亮显示,提升用户体验。通过为每个页面的body元素添加特定ID,并结合导航项的类名,可以轻松实现这一功能。 ... [详细]
  • 在尝试使用C# Windows Forms客户端通过SignalR连接到ASP.NET服务器时,遇到了内部服务器错误(500)。本文将详细探讨问题的原因及解决方案。 ... [详细]
  • This post discusses an issue encountered while using the @name annotation in documentation generation, specifically regarding nested class processing and unexpected output. ... [详细]
  • JavaScript中的数组是数据集合的核心结构之一,内置了多种实用的方法。掌握这些方法不仅能提高开发效率,还能显著提升代码的质量和可读性。本文将详细介绍数组的创建方式及常见操作方法。 ... [详细]
  • 本文介绍了一种基于选择排序思想的高效排序方法——堆排序。通过使用堆数据结构,堆排序能够在每次查找最大元素时显著提高效率。文章详细描述了堆排序的工作原理,并提供了完整的C语言代码实现。 ... [详细]
  • Linux环境下进程间通信:深入解析信号机制
    本文详细探讨了Linux系统中信号的生命周期,从信号生成到处理函数执行完毕的全过程,并介绍了信号编程中的注意事项和常见应用实例。通过分析信号在进程中的注册、注销及处理过程,帮助读者理解如何高效利用信号进行进程间通信。 ... [详细]
  • 本文探讨了符号三角形问题,该问题涉及由相同数量的“+”和“-”符号组成的三角形。通过递归回溯法,可以有效地搜索并计算符合条件的符号三角形的数量。 ... [详细]
  • 本文探讨了在 SQL Server 中使用 JDBC 插入数据时遇到的问题。通过详细分析代码和数据库配置,提供了解决方案并解释了潜在的原因。 ... [详细]
  • 本题要求在一组数中反复取出两个数相加,并将结果放回数组中,最终求出最小的总加法代价。这是一个经典的哈夫曼编码问题,利用贪心算法可以有效地解决。 ... [详细]
  • 本文详细介绍了一种高效的算法——线性筛法,用于快速筛选出一定范围内的所有素数。通过该方法,可以显著提高求解素数问题的效率。 ... [详细]
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社区 版权所有