C51 可持久化线段树 P1383 高级打字机

视频链接:237 可持久化线段树 P1383 高级打字机_哔哩哔哩_bilibili

 

 

Luogu P1383 高级打字机

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

const int N=100005;
#define mid ((l+r)>>1)
int root[N],tot,cnt;
int ls[N*20],rs[N*20],sum[N*20];
char ch[N*20];
//tot:节点个数, cnt:根节点个数
//sum:区间内的字母数
//ch: 叶子节点上的字母

void pushup(int u){ //上传
  sum[u]=sum[ls[u]]+sum[rs[u]];
}
void change(int &u,int v,int l,int r,char c){ //点修
  u=++tot; //动态开点
  ls[u]=ls[v];rs[u]=rs[v];sum[u]=sum[v];
  if(l==r){sum[u]=1;ch[u]=c;return;} //双指针同步搜索
  if(sum[ls[u]]<mid-l+1) change(ls[u],ls[v],l,mid,c);
  else change(rs[u],rs[v],mid+1,r,c);
  pushup(u);
}
char query(int u,int l,int r,int x){ //点查
  if(l==r) return ch[u];
  if(x<=sum[ls[u]]) return query(ls[u],l,mid,x);
  else return query(rs[u],mid+1,r,x-sum[ls[u]]);
}
int main(){
  int n; cin>>n;
  for(int i=1;i<=n;i++){
    char o,c; int x; cin>>o;
    if(o=='T'){ //在文章末尾添加一个字母
      cin>>c; ++cnt;
      change(root[cnt],root[cnt-1],1,n,c);
    }
    if(o=='U'){ //撤销最后的x次修改操作
      cin>>x; ++cnt;
      root[cnt]=root[cnt-x-1];
    }
    if(o=='Q'){ //查询第x个字母
      cin>>x;
      cout<<query(root[cnt],1,n,x)<<endl;
    }
  }
  return 0;
}

 

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

const int N=100005;
#define mid ((l+r)>>1)
int root[N],tot,cnt;
int ls[N*20],rs[N*20],sum[N*20];
char ch[N*20];
//tot:节点个数, cnt:根节点个数
//sum:区间内的字母数
//ch: 叶子节点上的字母

void change(int &u,int v,int l,int r,char c){ //点修
  u=++tot; //动态开点
  ls[u]=ls[v];rs[u]=rs[v];sum[u]=sum[v]+1;
  if(l==r){sum[u]=1;ch[u]=c;return;} //双指针同步搜索
  if(sum[ls[u]]<mid-l+1) change(ls[u],ls[v],l,mid,c);
  else change(rs[u],rs[v],mid+1,r,c);
}
char query(int u,int l,int r,int x){ //点查
  if(l==r) return ch[u];
  if(x<=sum[ls[u]]) return query(ls[u],l,mid,x);
  else return query(rs[u],mid+1,r,x-sum[ls[u]]);
}
int main(){
  int n; cin>>n;
  for(int i=1;i<=n;i++){
    char o,c; int x; cin>>o;
    if(o=='T'){ //在文章末尾添加一个字母
      cin>>c; ++cnt;
      change(root[cnt],root[cnt-1],1,n,c);
    }
    if(o=='U'){ //撤销最后的x次修改操作
      cin>>x; ++cnt;
      root[cnt]=root[cnt-x-1];
    }
    if(o=='Q'){ //查询第x个字母
      cin>>x;
      cout<<query(root[cnt],1,n,x)<<endl;
    }
  }
  return 0;
}

 

posted @ 2023-10-24 15:37  董晓  阅读(172)  评论(0编辑  收藏  举报