分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 软件开发

BZOJ 1014 [JSOI2008]火星人prefix | Splay维护哈希值

发布时间:2023-09-06 01:33责任编辑:白小东关键词:暂无标签

题目:


题解:

#include<cstdio>#include<algorithm>#include<cstring>typedef long long ll;#define N 100010#define Base 29#define which(x) (ls[fa[(x)]]==(x))using namespace std;int n,m,idx,root,fa[N],ls[N],rs[N],val[N],sz[N],a,b;ll hsh[N],pw[N];char s[N],op[10];void upt(int u){ ???sz[u]=sz[ls[u]]+sz[rs[u]]+1; ???hsh[u]=hsh[ls[u]]+val[u]*pw[sz[ls[u]]]+hsh[rs[u]]*pw[sz[ls[u]]+1];}void rotate(int u){ ???int v=fa[u],w=fa[v],b=which(u)?rs[u]:ls[u]; ???if (w) which(v)?ls[w]=u:rs[w]=u; ???which(u)?(ls[v]=b,rs[u]=v):(rs[v]=b,ls[u]=v); ???fa[u]=w,fa[v]=u; ???if (b) fa[b]=v; ???upt(v),upt(u);}void splay(int u,int tar){ ???while (fa[u]!=tar) ???{ ???if (fa[fa[u]]!=tar) ???????(which(u)==which(fa[u]))?rotate(fa[u]):rotate(u); ???rotate(u); ???} ???if (!tar) root=u;}int build(int l,int r,int pre){ ???if (l>r) return 0; ???int u=++idx,mid=l+r>>1; ???val[u]=s[mid]-‘a‘+1,fa[u]=pre; ???ls[u]=build(l,mid-1,u); ???rs[u]=build(mid+1,r,u); ???upt(u); ???return u;}int find(int x){ ???int u=root; ???while(sz[ls[u]]!=x) ???if (x<=sz[ls[u]]-1) u=ls[u]; ???else x-=sz[ls[u]]+1,u=rs[u]; ???return u;}void insert(int pos,int x){ ???int u=find(pos),v=find(pos+1); ???splay(u,0),splay(v,u); ???ls[v]=++idx,fa[idx]=v,val[idx]=x,sz[idx]=1; ???splay(idx,0);}void change(int pos,int x){ ???int u=find(pos); ???val[u]=x; ???splay(u,0);}ll gethsh(int pos,int len){ ???int u=find(pos-1),v=find(pos+len); ???splay(u,0),splay(v,u); ???return hsh[ls[v]];}int query(int a,int b){ ???int l=0,r=sz[root]-max(a,b)-1,mid; ???while (l<r) ???{ ???mid=l+r+1>>1; ???if (gethsh(a,mid)==gethsh(b,mid)) l=mid; ???else r=mid-1; ???} ???return l;}int main(){ ???scanf("%s",s+1); ???n=strlen(s+1); ???pw[0]=1; ???for (int i=1;i<N;i++) ???pw[i]=pw[i-1]*Base; ???root=build(0,n+1,0); ???scanf("%d",&m); ???while (m--) ???{ ???scanf("%s",op); ???if (op[0]==‘Q‘) ???{ ???????scanf("%d%d",&a,&b); ???????printf("%d\n",query(a,b)); ???} ???else if (op[0]==‘I‘) ???{ ???????int pos; ???????scanf("%d%s",&pos,op); ???????insert(pos,op[0]-‘a‘+1); ???} ???else if (op[0]==‘R‘) ???{ ???????int pos; ???????scanf("%d%s",&pos,op); ???????change(pos,op[0]-‘a‘+1); ???} ???} ???return 0;}

BZOJ 1014 [JSOI2008]火星人prefix | Splay维护哈希值

原文地址:https://www.cnblogs.com/mrsheep/p/8137022.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved