Message
Message
h>
using namespace std;
struct segtree{
vector<vector<int>> el;
vector<int> lazy;
int size;
segtree(int n){
size=1;
while(size<=n) size<<=1;
el.assign(2*size,{0,0,0});
lazy.assign(2*size,0);
}
void update(int v, int tl, int tr, int l, int r, int p){
if(lazy[v]){
if(lazy[v]==1) {
int temp=el[v][2];
el[v][2]=el[v][1];
el[v][1]=el[v][0];
el[v][0]=temp;
}
else{
int temp=el[v][2];
el[v][2]=el[v][0];
el[v][0]=el[v][1];
el[v][1]=temp;
}
if(tl!=tr){
lazy[2*v]=(lazy[2*v]+lazy[v])%3;
lazy[2*v+1]=(lazy[2*v+1]+lazy[v])%3;
}
lazy[v]=0;
}
if(tl>r||tr<l) return;
if(l<=tl&&tr<=r){
if(p==1) {
int temp=el[v][2];
el[v][2]=el[v][1];
el[v][1]=el[v][0];
el[v][0]=temp;
}
else{
int temp=el[v][2];
el[v][2]=el[v][0];
el[v][0]=el[v][1];
el[v][1]=temp;
}
if(tl!=tr){
lazy[2*v]=(lazy[2*v]+p)%3;
lazy[2*v+1]=(lazy[2*v+1]+p)%3;
}
return;
}
int tm=(tl+tr)/2;
update(2*v,tl,tm,l,r,p);
update(2*v+1,tm+1,tr,l,r,p);
el[v][0]=el[2*v][0]+el[2*v+1][0];
el[v][1]=el[2*v][1]+el[2*v+1][1];
el[v][2]=el[2*v][2]+el[2*v+1][2];
}
}
vector<ll> query(int l, int r){
auto it=query(1,0,size-1,l,r);
vector<ll> x= {it.first, it.second.first, it.second.second};
return x;
}
};
signed main(){
ios_base::sync_with_stdio(0);
cin.tie(0);
int n,q;
cin>>n>>q;
vector<int> a(n);
vector<int> b(n);
segtree st(n);
for(int i=0;i<n;i++){
char p;
cin>>p;
int x=p-'0';
a[i]=x%3;
b[i]=x%3;
if(i) a[i]=(a[i]+a[i-1])%3;
}
st.build(a);
while(q--){
int x;
cin>>x;
if(x==1){
int y,z;
cin>>y>>z;
z%=3;
int curr=z;
z=(z-b[y-1]+3)%3;
b[y-1]=curr;
if(z) st.update(y-1,n-1,z);
}
else{
int l, r;
cin>>l>>r;
auto p=st.query(l-1,r-1);
ll ans=0;
if(l-1){
auto q=st.query(l-2,l-2);
for(int i=0;i<3;i++) p[i]+=q[i];
}
else p[0]++;
for(auto it:p) ans+=((it*(it-1))/2);
cout<<ans<<"\n";
}
}