线段树求最长的相等字符串前缀
AC Code
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
char str1[N],str2[N];
int a[N];
struct node
{
int l,r,lazy;
int d[30];
}tr[N*4];
void pushup(int k)
{
for(int i=0;i<26;i++)
tr[k].d[i]=tr[k<<1].d[i]+tr[k<<1|1].d[i];
}
void pushdown(int k)
{
if(!tr[k].lazy) return ;
int idx=tr[k].lazy;
int c[30];
for(int i=0;i<26;i++)
c[i]=tr[k<<1].d[i];
for(int i=0;i<26;i++)
tr[k<<1].d[(i+idx)%26]=c[i];
for(int i=0;i<26;i++)
c[i]=tr[k<<1|1].d[i];
for(int i=0;i<26;i++)
tr[k<<1|1].d[(i+idx)%26]=c[i];
tr[k<<1].lazy+=tr[k].lazy;
tr[k<<1|1].lazy+=tr[k].lazy;
tr[k].lazy=0;
return ;
}
void build(int k,int l,int r)
{
tr[k].l=l,tr[k].r=r;
if(l==r)
{
tr[k].d[a[l]]=1;
return ;
}
int mid=(l+r)/2;
build(k<<1,l,mid);
build(k<<1|1,mid+1,r);
pushup(k);
}
void change(int k,int x,int y)
{
if(tr[k].l==x&&tr[k].r==x)
{
for(int i=0;i<26;i++)
tr[k].d[i]=0;
tr[k].d[y]=1;
return ;
}
pushdown(k);
int mid=(tr[k].l+tr[k].r)/2;
if(x<=mid) change(k<<1,x,y);
else change(k<<1|1,x,y);
pushup(k);
}
void modify(int k,int l,int r)
{
if(tr[k].l>=l&&tr[k].r<=r)
{
int c[30];
for(int i=0;i<26;i++)
c[i]=tr[k].d[i];
for(int i=0;i<26;i++)
tr[k].d[(i+1)%26]=c[i];
tr[k].lazy++;
return ;
}
pushdown(k);
int mid=(tr[k].l+tr[k].r)/2;
if(l<=mid) modify(k<<1,l,r);
if(r>mid) modify(k<<1|1,l,r);
pushup(k);
}
int query(int k)
{
if(tr[k].l==tr[k].r)
{
if(tr[k].d[0]!=1) return tr[k].l-1;
else return tr[k].l;
}
pushdown(k);
int mid=(tr[k].l+tr[k].r)/2;
if(tr[k<<1].d[0]==mid-tr[k].l+1) return query(k<<1|1);
else return query(k<<1);
}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
scanf("%s%s",str1+1,str2+1);
for(int i=1;i<=n;i++) a[i]=(str1[i]-str2[i]+26)%26;
build(1,1,n);
while(m--)
{
int op;
scanf("%d",&op);
if(op==1)
{
int x;
char y;
cin>>x>>y;
change(1,x,(y-str2[x]+26)%26);
}
else if(op==2)
{
int l,r;
scanf("%d%d",&l,&r);
modify(1,l,r);
}
else
{
int res=query(1);
printf("%d\n",res);
}
}
system("pause");
return 0;
}