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;
}