zoukankan      html  css  js  c++  java
  • LUOGU P3919 【模板】可持久化数组(主席树)

    传送门

    解题思路

      给每一时刻建一棵线段树维护当前时刻的值,然后修改的时候直接修改,查询的时候直接查,记住查询完后一定要复制。

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<cstdlib>
    
    using namespace std;
    const int MAXN = 1000005;
    
    inline int rd(){
    	int x=0,f=1;char ch=getchar();
    	while(!isdigit(ch)) {f=ch=='-'?0:1;ch=getchar();}
    	while(isdigit(ch))  {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
    	return f?x:-x;
    }
    
    int n,m,a[MAXN],rt[MAXN],cnt;
    int val[MAXN*22],ls[MAXN*22],rs[MAXN*22];
    
    int build(int l,int r){
    	int now=++cnt,mid=(l+r)>>1;
    	if(l==r) {
    		val[now]=rd();
    		return now;
    	}
    	ls[now]=build(l,mid);rs[now]=build(mid+1,r);
    	return now;
    }
    
    int update(int pre,int l,int r,int x,int k){
    	int now=++cnt,mid=(l+r)>>1;
    	ls[now]=ls[pre];rs[now]=rs[pre];val[now]=val[pre];
    	if(l==r) {val[now]=k;return now;}
    	if(x<=mid) ls[now]=update(ls[pre],l,mid,x,k);
    	else rs[now]=update(rs[pre],mid+1,r,x,k);
    	return now; 
    }
    
    int query(int pre,int l,int r,int x){
    	if(l==r) return val[pre];
    	int mid=(l+r)>>1;
    	if(x<=mid) return query(ls[pre],l,mid,x);
    	else return query(rs[pre],mid+1,r,x);
    }
    
    int main(){
    	n=rd(),m=rd();rt[0]=build(1,n);int pre,op,x,y;
    	for(int i=1;i<=m;i++){
    		pre=rd(),op=rd(),x=rd();
    		if(op==1) y=rd(),rt[i]=update(rt[pre],1,n,x,y);
    		else printf("%d
    ",query(rt[pre],1,n,x)),rt[i]=rt[pre];
    	}	
    	return 0;
    }
    
  • 相关阅读:
    P1428 小鱼比可爱
    P5727 【深基5.例3】冰雹猜想
    P1427 小鱼的数字游戏
    P1047 [NOIP2005 普及组] 校门外的树
    P5729 工艺品制作
    P5728 【深基5.例5】旗鼓相当的对手
    CodeSmith使用和语法简介
    系统缓存
    FLV视频转换的利器 ffmpeg.exe
    Vs.Net方向将Excel数据导入到数据库
  • 原文地址:https://www.cnblogs.com/sdfzsyq/p/9961290.html
Copyright © 2011-2022 走看看