RT.
写的是分块。
#include<bits/stdc++.h>
//#pragma GCC optimize("Ofast")
#define gt getchar
#define pt putchar
#define y1 y233
typedef long long ll;
//typedef __int128 lll;
typedef unsigned long long ull;
const int N=1e5+5;
const int V=320;
using namespace std;
inline bool __(char ch){return ch>=48&&ch<=57;}
inline int read(){
int x=0;bool sgn=0;char ch=gt();
while(!__(ch)&&ch!=EOF){sgn|=(ch=='-');ch=gt();}
while(__(ch)){x=(x<<1)+(x<<3)+(ch-48);ch=gt();}
return sgn?-x:x;
}
template<class T>
inline void print(T x){
static char st[70];short top=0;
if(x<0)pt('-');
do{st[++top]=x>=0?(x%10+48):(-(x%10)+48),x/=10;}while(x);
while(top)pt(st[top--]);
}
template<class T>
inline void printsp(T x){
static char st[70];short top=0;
if(x<0)pt('-');
do{st[++top]=x>=0?(x%10+48):(-(x%10)+48),x/=10;}while(x);
while(top)pt(st[top--]);pt(32);
}
template<class T>
inline void println(T x){
static char st[70];short top=0;
if(x<0)pt('-');
do{st[++top]=x>=0?(x%10+48):(-(x%10)+48),x/=10;}while(x);
while(top)pt(st[top--]);pt(10);
}
inline void put_str(string s){
int siz=s.size();
for(int i=0;i<siz;++i) pt(s[i]);
printf("\n");
}
int n,q,num[30],cnt[V][30],num2[30],numb,cntb;
char lval[V],rval[V],s[N];
bool is_order[V];
inline int id(int x){return (x+numb-1)/numb;}
inline int left(int x){return (x-1)*numb+1;}
inline int right(int x){return min(n,x*numb);}
inline void init(){
for(int i=1;i<=cntb;++i){
is_order[i]=1;
int l=left(i),r=right(i);
lval[i]=s[l],rval[i]=s[r];
for(int j=l+1;j<=r;++j){
if(s[j]<s[j-1]){
is_order[i]=0;
break;
}
}
for(int j=l;j<=r;++j) cnt[i][s[j]-'a'+1]++;
}
}
inline void update(int pos,char val){
char lst=s[pos];
int bh=id(pos);
s[pos]=val,num[lst-'a'+1]--,num[val-'a'+1]++;
cnt[bh][lst-'a'+1]--,cnt[bh][lst-'a'+1]++;
int l=left(bh),r=right(bh);
bool flag=1;
for(int j=l+1;j<=r;++j){
if(s[j]<s[j-1]){
flag=0;
break;
}
}
is_order[bh]=flag;
if(pos==l)lval[bh]=val;
if(pos==r)rval[bh]=val;
}
inline bool query(int l,int r){
int L=id(l),R=id(r);
for(int i=1;i<=26;++i) num2[i]=0;
if(L==R){
for(int i=l+1;i<=r;++i) if(s[i]<s[i-1])return 0;
for(int i=l;i<=r;++i) num2[s[i]-'a'+1]++;
for(char ch=s[l]+1;ch<s[r];++ch) if(num2[ch-'a'+1]!=num[ch-'a'+1])return 0;
return 1;
}
int r1=right(L),l2=left(R);
for(int i=l+1;i<=r1;++i) if(s[i]<s[i-1])return 0;
for(int i=l2+1;i<=r;++i) if(s[i]<s[i-1])return 0;
for(int pos=L+1;pos<R;++pos) if(!is_order[pos])return 0;
for(int pos=L+1;pos<=R;++pos){
int lstr=right(pos-1);
if(s[lstr+1]<s[lstr])return 0;
}
for(int i=l;i<=r1;++i) num2[s[i]-'a'+1]++;
for(int i=l2;i<=r;++i) num2[s[i]-'a'+1]++;
for(int pos=L+1;pos<R;++pos) for(int t=1;t<=26;++t) num2[t]+=cnt[pos][t];
for(char qwq=s[l]+1;qwq<s[r];++qwq) if(num2[qwq-'a'+1]!=num[qwq-'a'+1])return 0;
return 1;
}
signed main(){
n=read(),numb=sqrt(n);
cntb=(n+numb-1)/numb;
scanf("%s",s+1);
for(int i=1;i<=n;++i) num[s[i]-'a'+1]++;
init();
q=read();
while(q--){
int opt=read(),x,l,r;
char c;
if(opt==1){
x=read();
cin>>c;
update(x,c);
}else{
l=read(),r=read();
printf(query(l,r)?"Yes\n":"No\n");
}
}
return 0;
}