实际上式可持久化数组,利用线段树进行操作
#include <bits/stdc++.h>
#define inf 0x7fffffff
#define ll long long
#define int long long
//#define double long double
//#define double long long
#define re int
//#define void inline void
#define eps 1e-8
//#define mod 1e9+7
#define ls(p) p<<1
#define rs(p) p<<1|1
#define pi acos(-1.0)
#define pb push_back
#define mk make_pair
#define P pair < int , int >
using namespace std;
//const int mod=9901;
//const int inf=1e18;
const int M=1e8;
const int N=2e7+5;//??????.???? 4e8
struct node
{
int l,r,sum,rc,lc;
}e[N];
int n,m,tot;
int root[N];
void bulid(int &p,int l,int r)
{
p=++tot;
e[p].l=l,e[p].r=r;
if(l==r)
{
scanf("%lld",&e[p].sum);
return;
}
int mid=(l+r)>>1;
bulid(e[p].lc,l,mid);
bulid(e[p].rc,mid+1,r);
}
void insert(int &p,int pre,int pos,int v)
{
p=++tot;
e[p].lc=e[pre].lc;
e[p].rc=e[pre].rc;
e[p].l=e[pre].l;
e[p].r=e[pre].r;
e[p].sum=e[pre].sum;
if(e[p].l==e[p].r)
{
e[p].sum=v;
return;
}
int mid=(e[p].l+e[p].r)>>1;
if(pos<=mid) insert(e[p].lc,e[pre].lc,pos,v);
else insert(e[p].rc,e[pre].rc,pos,v);
}
int ask(int p,int pos)
{
if(e[p].r==e[p].l) return e[p].sum;
int mid=(e[p].l+e[p].r)>>1;
if(pos<=mid) return ask(e[p].lc,pos);
else return ask(e[p].rc,pos);
}
void solve()
{
cin>>n>>m;
bulid(root[0],1,n);
for(re i=1;i<=m;i++)
{
int pre,op,x,y;
scanf("%lld%lld%lld",&pre,&op,&x);
if(op==1)
{
scanf("%lld",&y);
insert(root[i],root[pre],x,y);
}
else printf("%lld\n",ask(root[pre],x)),root[i]=root[pre];
}
}
signed main()
{
int T=1;
// cin>>T;
for(int index=1;index<=T;index++)
{
solve();
// puts("");
}
return 0;
}
/*
*/