P4036 [JSOI2008] 火星人

先暴力水过了wwwwwwwwwwwwwww

#include<bits/stdc++.h>
//================================================
//#define LOCAL FLANDRE KAWAII
#ifndef LOCAL
    constexpr int SIZE(1<<20);
    char in[SIZE],out[SIZE],*p1=in,*p2=in,*p3=out;
    #define getchar() (p1==p2&&(p2=(p1=in)+fread(in,1,SIZE,stdin),p1==p2)?EOF:*p1++)
    #define flush() (fwrite(out,1,p3-out,stdout))
    #define putchar(x) (p3==out+SIZE&&(flush(),p3=out),*p3++=(x))
    class Flush{public:~Flush(){flush();}}_;
#endif
inline int read(){
	int x(0);bool f(0);char ch=getchar();
	for(;ch<'0'||ch>'9';ch=getchar()) f^=ch=='-';
	for(;ch>='0'&&ch<='9';ch=getchar()) x=(x<<1)+(x<<3)+(ch^48);
	return f?x=-x:x;
}
inline void write(int x){
	x<0?x=-x,putchar('-'):0;static short Sta[50],top(0);
	do{Sta[++top]=x%10;x/=10;}while(x);
	while(top) putchar(Sta[top--]|48);
	putchar('\n');
}
inline void readc(char &c){
	c=getchar();while(isspace(c))c=getchar();
}
//================================================
std::vector <char> s;
std::string s1;
inline void check(){
	std::cout<<"CH:"<<'\n';
	for(auto i:s){std::cout<<i<<" " ;}
	std::cout<<'\n';
}
int m,len;
int main(){
	std::cin>>s1;len=s1.size();
	for(auto i:s1) s.push_back(i);
	char opt,ch;
	m=read();
	for(int i=1,x,y,cnt=0;i<=m;++i){
		readc(opt);x=read();
		switch(opt){
			case 'Q':y=read();
				for(int j=x-1,k=y-1;k<len;++j,++k){if(s[j]==s[k]) cnt++;else break;}
				write(cnt);cnt=0;break;
			case 'R':readc(ch);s[x-1]=ch;break;
			case 'I':readc(ch);len++;s.insert(s.begin()+x,ch);break;
		}
//		check();
	}
	return 0;
}

正解:哈希+二分求最长公共前缀,再用平衡树大力维护区间即可

code
#include<bits/stdc++.h>
//================================================
//#define LOCAL FLANDRE KAWAII
#ifndef LOCAL
    constexpr int SIZE(1<<20);
    char in[SIZE],out[SIZE],*p1=in,*p2=in,*p3=out;
    #define getchar() (p1==p2&&(p2=(p1=in)+fread(in,1,SIZE,stdin),p1==p2)?EOF:*p1++)
    #define flush() (fwrite(out,1,p3-out,stdout))
    #define putchar(x) (p3==out+SIZE&&(flush(),p3=out),*p3++=(x))
    class Flush{public:~Flush(){flush();}}_;
#endif
inline int read(){
	int x(0);bool f(0);char ch=getchar();
	for(;ch<'0'||ch>'9';ch=getchar()) f^=ch=='-';
	for(;ch>='0'&&ch<='9';ch=getchar()) x=(x<<1)+(x<<3)+(ch^48);
	return f?x=-x:x;
}
inline void write(int x){
	x<0?x=-x,putchar('-'):0;static short Sta[50],top(0);
	do{Sta[++top]=x%10;x/=10;}while(x);
	while(top) putchar(Sta[top--]|48);
	putchar('\n');
}
inline void readc(char &c){
	c=getchar();while(isspace(c))c=getchar();
}
//================================================ 
using ull=unsigned long long;
constexpr int N(500005),base(131);
int m,rt,len;
char s[N];
ull p[N],h[N],val[N];
int ch[N][2],siz[N],fa[N];
namespace Splay{
	inline void upd(int x){
		siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+1;
		h[x]=h[ch[x][0]]*p[siz[ch[x][1]]+1]+val[x]*p[siz[ch[x][1]]]+h[ch[x][1]];
	}
	inline bool chk(int x){return x==ch[fa[x]][1];}
	inline void rotate(int x){
		int f=fa[x],k=chk(x),ff=fa[f],kk=chk(f);
		fa[ch[f][k]=ch[x][k^1]]=f;
		fa[ch[x][k^1]=f]=x;
		fa[x]=ff;if(ff) ch[ff][kk]=x;
		upd(f);upd(x);
	}
	inline void splay(int x,int goal=0){
		for(int f=fa[x];f!=goal;rotate(x),f=fa[x])
			if(fa[f]!=goal) rotate(chk(x)==chk(f)?f:x);
		if(!goal) rt=x;
	}
	inline int Kth(int k){
		int now=rt;
		while(1){
			if(k==siz[ch[now][0]]+1) return now;
			if(k>siz[ch[now][0]]+1){k-=(siz[ch[now][0]]+1);now=ch[now][1];} 
			else now=ch[now][0]; 
		}
	}
	void build(int root,int l,int r){
		if(l>r) return;
		int mid=l+r>>1;
		if(mid>root) ch[root][1]=mid;
		else ch[root][0]=mid;
		fa[mid]=root;siz[mid]=1;
		if(l==r) return;
		build(mid,l,mid-1);build(mid,mid+1,r);
		upd(mid); 
	}
	ull gethash(int l,int r){
    	int x=Kth(l);splay(x,0);
    	int y=Kth(r+2);splay(y,x);
    	return h[ch[y][0]];
	}
}
using std::cout;
using std::cin;
inline int query(int x,int y){
	if(x>y) std::swap(x,y);
	int l=0,r=len-y-1;
	while(l<r){
		int mid=l+r+1>>1;
		if(Splay::gethash(x,x+mid-1)==Splay::gethash(y,y+mid-1)) l=mid;
		else r=mid-1;
	}
	return l;
}
inline void remove(int x,int v){
	Splay::splay(Splay::Kth(x+1));
	val[rt]=v;
	Splay::upd(rt); 
}
inline void insert(int x,int v){
	int l=Splay::Kth(x+1);Splay::splay(l);
	int r=Splay::Kth(x+2);Splay::splay(r,l);
	fa[ch[r][0]=++len]=r;
	siz[len]=1;val[len]=h[len]=v;
	Splay::splay(len);
}
int main(){
	cin>>s+1;m=read();len=strlen(s+1);
	p[0]=1;for(int i=1;i<=len*2;++i) p[i]=p[i-1]*base*1ull;
	for(int i=2;i<=len+1;++i) h[i]=val[i]=s[i-1]-'a'+1;
	Splay::build(rt,1,len+2);
	len=len+2;rt=len+1>>1;
	char opt,c;
	while(m--){
		readc(opt);
		int l,r,mid,x,y;
		switch(opt){
			case 'Q':
				x=read();y=read();
				write(query(x,y));
				break;
			case 'R':
				x=read();readc(c);
				remove(x,c-'a'+1);
				break;
			case 'I':
				x=read();readc(c);
				insert(x,c-'a'+1);
				break;
		}
	}
	return 0;
}
posted @ 2023-06-01 18:43  Flandreqwq  阅读(17)  评论(0编辑  收藏  举报