luogu P3919 [模板]可持久化数组(可持久化线段树/平衡树)(主席树)

本文详细介绍了可持久化线段树的数据结构原理及其实现过程,通过洛谷P3919题目实例展示了如何使用该数据结构解决复杂查询问题。文章包括核心代码解析、构造方法、修改操作及查询功能的实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

luogu P3919 [模板]可持久化数组(可持久化线段树/平衡树) 题目

#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iomanip>
#include<algorithm>
#include<ctime>
#include<queue>
#include<stack>
#define rg register
#define il inline
#define lst long long
#define N 1000050
using namespace std;

int n,Q,cnt;
int val[N];
int root[N];
struct TREE{
    int ls,rs,v;
}ljl[N*25];

il int read()
{
    rg int s=0,m=1;rg char ch=getchar();
    while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
    if(ch=='-')m=-1,ch=getchar();
    while(ch>='0'&&ch<='9')s=(s<<3)+(s<<1)+ch-'0',ch=getchar();
    return s*m;
}

il void build(rg int &now,rg int le,rg int ri)
//现在所在的点(可往回传参),  左端点,   右端点
{
    ljl[++cnt]=ljl[now];//新开一个点……
    now=cnt;//保证now指的是当点这个点,因为还要传回去赋值给“爸爸的左/右儿子”……具体看后面的递归build
    if(le==ri){ljl[now].v=val[le];return;}//如果到单点赋值就ojbk了(同线段树)
    rg int mid=(le+ri)>>1;
    build(ljl[now].ls,le,mid),build(ljl[now].rs,mid+1,ri);
    //建造左儿子和右儿子,本节点向他们的指针在递归函数往回传参时会赋值(一切都源于一个美丽的“ & ”)
}

void Modify(rg int &now,rg int le,rg int ri,rg int kk,rg int x)//很像build
//现在所在的点(可往回传参),左端点,右端点,要修改的点编号,修改后的值
{
    ljl[++cnt]=ljl[now];//又要开点了……
    now=cnt;//保证now指的是当点这个点,因为还要传回去赋值给“爸爸的左/右儿子”……具体看后面的递归Modify
    if(le==ri){ljl[now].v=x;return;}//照样赋值
    rg int mid=(le+ri)>>1;
    if(kk<=mid)Modify(ljl[now].ls,le,mid,kk,x);
    else Modify(ljl[now].rs,mid+1,ri,kk,x);
    //kk在mid左边,就建左孩子,否则建右孩子……需要模拟哦……
}

int Query(rg int now,rg int le,rg int ri,rg int kk)
{
    if(le==ri)return ljl[now].v;
    rg int mid=(le+ri)>>1;
    if(kk<=mid)return Query(ljl[now].ls,le,mid,kk);
    else return Query(ljl[now].rs,mid+1,ri,kk);
}

int main()
{
    n=read(),Q=read();
    for(rg int i=1;i<=n;++i)val[i]=read();
    build(root[0],1,n);//先按原来的值建一棵线段树在0号根上
    for(rg int i=1;i<=Q;++i)
    {
        rg int edi=read(),type=read();//历史版本edi,询问type
        if(type==1)
        {
            rg int kk=read(),x=read();//把kk号的val改成x
            root[i]=root[edi];//先把根连过来,再修改!
            Modify(root[i],1,n,kk,x);//从根开始,左,右端点,修改的编号,修改成的值
        }
        else
        {
            rg int kk=read();
            printf("%d\n",Query(root[edi],1,n,kk));//当前节点(也就是edi时的根),左,右端点,询问第kk号的值
            root[i]=root[edi];//这个依题,还是弄过来吧……
        }
    }
    return 0;
}

 

``` #include <bits/stdc++.h> #define ll long long #define lb(x) x&(-x) using namespace std; const ll N=1e5,M=5e5,TR=2e7; struct node{ ll ls,rs,w,val; }tr[TR+5]; ll n,m; ll a[N+5]; vector<ll> v[M+5]; ll b[M+5],cntb; ll root[M+5],cnttr; ll trr[N+5]; ll minn; void modify(ll x,ll y){ if(!x) return; for(ll i=x;i<=n;i+=lb(i)){ trr[i]+=y; } return; } ll query(ll x){ ll s=0; for(ll i=x;i;i-=lb(i)){ s+=trr[i]; } return s; } ll query(ll l,ll r){ return query(r)-query(l-1); } void split(ll p,ll v,ll &x,ll &y){ if(!p){ x=y=0; return; } if(tr[p].val<=v){ x=p; split(tr[p].rs,v,tr[p].rs,y); } else{ y=p; split(tr[p].ls,v,x,tr[p].ls); } return; } void merge(ll x,ll y,ll &p){ if(!x || !y){ p=x+y; return; } if(tr[x].w>=tr[y].w){ p=x; merge(tr[p].rs,y,tr[p].rs); } else{ p=y; merge(x,tr[p].ls,tr[p].ls); } return; } void build(ll &p,ll l,ll r){ if(l>r) return; ll mid=(l+r)>>1; p=++cnttr; tr[p]=(node){0,0,rand(),b[mid]}; build(tr[cnttr].ls,l,mid-1); build(tr[cnttr].rs,mid+1,r); return; } void dfs(ll p,ll x){ if(!p) return; minn=min(minn,p); dfs(tr[p].ls,x); ll pos=tr[p].val; modify(pos,-a[pos]+a[pos]/x); a[pos]/=x; if(a[pos]%x==0) b[++cntb]=pos; dfs(tr[p].rs,x); return; } void work(ll p){ if(!p) return; work(tr[p].ls); cout<<p<<" "<<tr[p].ls<<" "<<tr[p].rs<<" "<<tr[p].val<<endl; work(tr[p].rs); return; } int main(){ srand(time(NULL)); // srand(5); scanf("%lld%lld",&n,&m); for(ll i=1;i<=n;i++){ scanf("%lld",&a[i]); for(ll j=1;j*j<=a[i];j++){ if(i%j==0){ v[j].push_back(i); if(j*j!=a[i]) v[i/j].push_back(i); } } modify(i,a[i]); } for(ll i=1;i<=N;i++){ cntb=0; // cout<<i<<"ooooooo\n"; for(ll j:v[i]){ b[++cntb]=j; // cout<<j<<" "; } // cout<<endl; build(root[i],1,cntb); } while(m--){ ll op,l,r,v; scanf("%lld%lld%lld",&op,&l,&r); if(op==1){ scanf("%lld",&v); if(v<=1) continue; ll x=0,y=0,z=0; split(root[v],r,x,z); split(x,l-1,x,y); // work(y); minn=TR; cntb=0; dfs(y,v); // cnttr=minn-1; build(y,1,cntb); merge(x,y,x); merge(x,z,root[v]); } else printf("%lld\n",query(l,r)); } return 0; } /* 5 1 1 2 3 4 5 1 1 5 2 */ ``` # P3987 我永远喜欢珂朵莉~ ## 题目背景 http://sukasuka-anime.com/ 戒不掉的珂毒 出不动的分块 ![](https://cdn.luogu.com.cn/upload/pic/11191.png) ![](https://cdn.luogu.com.cn/upload/pic/11192.png) ![](https://cdn.luogu.com.cn/upload/pic/11193.png) 哦对了有没有想买BD的珂学家啊?支持一下墨鱼吧~ 或者有没有人想来手办众筹啊? ## 题目描述 给珂朵莉一个长为 $n$ 的非负数序列 $a$,支持以下两个操作: - $\verb!1 l r x!$:把区间 $[l,r]$ 中所有 $x$ 的倍数除以 $x$。 - $\verb!2 l r!$:查询区间 $[l,r]$ 内元素的和。 珂朵莉很可爱,所以你要帮珂朵莉写这个题。 ## 输入格式 第一行两个数表示 $n,m$。 第二行 $n$ 个非负整数表示 $a_i$。 之后 $m$ 行每行一个操作: - $\verb!1 l r x!$:把区间 $[l,r]$ 中所有 $x$ 的倍数除以 $x$。 - $\verb!2 l r!$:查询区间 $[l,r]$ 内元素的和。 ## 输出格式 对于每次询问,输出一行一个数表示答案。 ## 输入输出样例 #1 ### 输入 #1 ``` 5 3 1 2 3 4 5 2 1 5 1 1 5 2 2 1 5 ``` ### 输出 #1 ``` 15 12 ``` ## 说明/提示 ### 数据范围及约定 $1 \le n , m \le 10^5$,$0 \le a_i \le 5\times 10^5$,$1 \le x \le 5\times 10^5$。 上面代码过不了样例
08-14
内容概要:本文深入探讨了Kotlin语言在函数式编程和跨平台开发方面的特性和优势,结合详细的代码案例,展示了Kotlin的核心技巧和应用场景。文章首先介绍了高阶函数和Lambda表达式的使用,解释了它们如何简化集合操作和回调函数处理。接着,详细讲解了Kotlin Multiplatform(KMP)的实现方式,包括共享模块的创建和平台特定模块的配置,展示了如何通过共享业务逻辑代码提高开发效率。最后,文章总结了Kotlin在Android开发、跨平台移动开发、后端开发和Web开发中的应用场景,并展望了其未来发展趋势,指出Kotlin将继续在函数式编程和跨平台开发领域不断完善和发展。; 适合人群:对函数式编程和跨平台开发感兴趣的开发者,尤其是有一定编程基础的Kotlin初学者和中级开发者。; 使用场景及目标:①理解Kotlin中高阶函数和Lambda表达式的使用方法及其在实际开发中的应用场景;②掌握Kotlin Multiplatform的实现方式,能够在多个平台上共享业务逻辑代码,提高开发效率;③了解Kotlin在不同开发领域的应用场景,为选择合适的技术栈提供参考。; 其他说明:本文不仅提供了理论知识,还结合了大量代码案例,帮助读者更好地理解和实践Kotlin的函数式编程特性和跨平台开发能力。建议读者在学习过程中动手实践代码案例,以加深理解和掌握。
内容概要:本文深入探讨了利用历史速度命令(HVC)增强仿射编队机动控制性能的方法。论文提出了HVC在仿射编队控制中的潜在价值,通过全面评估HVC对系统的影响,提出了易于测试的稳定性条件,并给出了延迟参数与跟踪误差关系的显式不等式。研究为两轮差动机器人(TWDRs)群提供了系统的协调编队机动控制方案,并通过9台TWDRs的仿真和实验验证了稳定性和综合性能改进。此外,文中还提供了详细的Python代码实现,涵盖仿射编队控制类、HVC增强、稳定性条件检查以及仿真实验。代码不仅实现了论文的核心思想,还扩展了邻居历史信息利用、动态拓扑优化和自适应控制等性能提升策略,更全面地反映了群体智能协作和性能优化思想。 适用人群:具备一定编程基础,对群体智能、机器人编队控制、时滞系统稳定性分析感兴趣的科研人员和工程师。 使用场景及目标:①理解HVC在仿射编队控制中的应用及其对系统性能的提升;②掌握仿射编队控制的具体实现方法,包括控制器设计、稳定性分析和仿真实验;③学习如何通过引入历史信息(如HVC)来优化群体智能系统的性能;④探索中性型时滞系统的稳定性条件及其在实际系统中的应用。 其他说明:此资源不仅提供了理论分析,还包括完整的Python代码实现,帮助读者从理论到实践全面掌握仿射编队控制技术。代码结构清晰,涵盖了从初始化配置、控制律设计到性能评估的各个环节,并提供了丰富的可视化工具,便于理解和分析系统性能。通过阅读和实践,读者可以深入了解HVC增强仿射编队控制的工作原理及其实际应用效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值