记录编号 360817 评测结果 AAAAAAAAAA
题目名称 [JSOI 2008]火星人prefix 最终得分 100
用户昵称 GravatarFoolMike 是否通过 通过
代码语言 C++ 运行时间 9.168 s
提交时间 2017-01-01 16:08:59 内存使用 30.30 MiB
显示代码纯文本
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
typedef unsigned long long ll;
const int N=5e5+10,NP=3;
const ll p[NP]={1e6+7,1e7+7,1e8+7};
char str[N],ch[10];int x,y;
int n,q,son[N][2],fa[N],k[N],s[N],Root,top;
bool root[N];
ll hs[N][NP],mi[N][NP];
#define lc son[x][0]
#define rc son[x][1]
void update(int x){
	s[x]=s[lc]+s[rc]+1;
	for (int j=0;j<NP;j++)
		hs[x][j]=((hs[lc][j]*26+k[x])*mi[s[rc]][j]+hs[rc][j])%p[j];
}
void New(int Fa,int K){//插入右子树 
	k[++top]=K;
	fa[son[Fa][1]=top]=Fa;
	update(top);
}
void rot(int x){
	int y=fa[x],z=fa[y];
	bool b=(x==son[y][1]);
	fa[son[y][b]=son[x][!b]]=y;
	fa[son[x][!b]=y]=x;
	fa[x]=z;
	if (son[z][0]==y) son[z][0]=x;else
	if (son[z][1]==y) son[z][1]=x;
	root[x]=root[y];root[y]=0;
	update(y);update(x);
}
void splay(int x){
	while (fa[x]){
		int y=fa[x],z=fa[y];
		if (root[y]||root[z]){rot(x);continue;}
		if (y==son[z][0]) rot(x==son[y][0]?y:x);
			else rot(x==son[y][1]?y:x);
		rot(x);
	}
	Root=x;
}
void find(int key){
	int x=Root;
	while (1){
		int i=s[lc]+1;
		if (i==key) break;
		if (key>i) key-=i,x=rc;
			else x=lc;
	}
	splay(x);
}
void hash(int x,int L,ll *ans){//以x开头,长为L的hash值 
	find(x);find(x+L+1);
	int le=son[Root][0],th=son[le][1];
	for (int j=0;j<NP;j++) ans[j]=hs[th][j];
}
void insert(int p,int c){
	find(p+1);
	find(p+2);
	int le=son[Root][0];
	New(le,c);
	update(le);update(Root);
	++n;
}
void change(int p,int c){
	find(p+1);
	k[Root]=c;
	update(Root);
}
int lcp(int x,int y){
	int l=0,r=n+1-max(x,y);
	ll hsx[NP],hsy[NP];
	while (l!=r){
		int mid=(l+r)>>1;
		hash(x,mid+1,hsx);
		hash(y,mid+1,hsy);
		bool check=1;
		for (int j=0;j<NP;j++)
		if (hsx[j]!=hsy[j]) check=0;
		if (check) l=mid+1;else r=mid;
	}
	return l;
}
void init(){
	for (int j=0;j<NP;j++) mi[0][j]=1;
	for (int i=1;i<=1e5;i++)
	for (int j=0;j<NP;j++)
		mi[i][j]=mi[i-1][j]*26%p[j];
	s[1]=2;s[2]=1;top=2;
	fa[son[1][1]=2]=1;
	root[Root=1]=1;
}
int main()
{
	freopen("bzoj_1014.in","r",stdin);
	freopen("bzoj_1014.out","w",stdout);
	init();
	scanf("%s%d",str+1,&q);
	int len=strlen(str+1);
	for (int i=1;i<=len;i++) insert(i-1,str[i]-'a');
	while (q--){
		scanf("%s%d",ch,&x);
		if (ch[0]=='Q')
			scanf("%d",&y),printf("%d\n",lcp(x,y));
		else
		if (ch[0]=='R')
			scanf("%s",ch),change(x,ch[0]-'a');
		else
		if (ch[0]=='I')
			scanf("%s",ch),insert(x,ch[0]-'a');
	}
	return 0;
}