#include<bits/stdc++.h> using namespace std; #define LL long long #define itn int #define ull unsigned long long struct node { int cnt[40]; int tag; int l,r; node() { l=r=0; tag=-1; memset(cnt,0,sizeof cnt); } } tree[(55000)*4]; int n,m; string s; int op; int x,y; char k; int cnt[40]; int szid(char s) { return toupper(s)-'A'; } void push_up(int now) { for(int i=0; i<=27; i++) { tree[now].cnt[i]=tree[now*2].cnt[i]+tree[now*2+1].cnt[i]; } return; } void push_down(int now) { if(tree[now].tag!=-1) { memset(tree[now*2].cnt,0,sizeof tree[now*2].cnt); memset(tree[now*2+1].cnt,0,sizeof tree[now*2+1].cnt); tree[now*2+1].tag=tree[now*2].tag=tree[now].tag; tree[now*2+1].cnt[tree[now].tag]=tree[now*2+1].r-tree[now*2+1].l+1; tree[now*2].cnt[tree[now].tag]=tree[now*2].r-tree[now*2].l+1; tree[now].tag=-1; } } void build(int now,int l,int r) { if(l>r)return; tree[now].l=l; tree[now].r=r; if(l==r) { tree[now].cnt[szid(s[l])]++; return; } int mid=(l+r)>>1; build(now*2,l,mid); build(now*2+1,mid+1,r); push_up(now); return; } void query_cx(int now,int nl,int nr) { int l=tree[now].l,r=tree[now].r; if(nl<=l&&nr>=r) { for(int i=0; i<=27; i++) { cnt[i]+=tree[now].cnt[i]; } return; } push_down(now); int mid=(l+r)>>1; if(mid>=nl)query_cx(now*2,nl,nr); if(mid<nr)query_cx(now*2+1,nl,nr); return; } void change(int now,int nl,int nr,int k) { int l=tree[now].l,r=tree[now].r; if(nl<=l&&nr>=r) { memset(tree[now].cnt,0,sizeof tree[now].cnt); tree[now].cnt[k]=r-l+1; tree[now].tag=k; return; } push_down(now); int mid=(l+r)>>1; if(mid>=nl)change(now*2,nl,nr,k); if(mid<nr)change(now*2+1,nl,nr,k); push_up(now); return; } void change_px(int nl,int nr) { int start=nl; for(int i=0; i<=27; i++) { if(cnt[i]==0)continue; change(1,start,start+cnt[i]-1,i); start+=cnt[i]; } return; } int query(int now,int nl,int nr,int k) { int l=tree[now].l,r=tree[now].r; if(nl<=l&&nr>=r) { return tree[now].cnt[k]; } push_down(now); int mid=(l+r)>>1; int ans=0; if(mid>=nl)ans+=query(now*2,nl,nr,k); if(mid<nr)ans+=query(now*2+1,nl,nr,k); return ans; } int main() { cin>>n>>m>>s; s=" "+s; build(1,1,n); while(m--) { cin>>op; if(op==1) { cin>>x>>y>>k; cout<<query(1,x,y,szid(k))<<"\n"; } else if(op==2) { cin>>x>>y>>k; change(1,x,y,szid(k)); } else { cin>>x>>y; memset(cnt,0,sizeof cnt); query_cx(1,x,y); change_px(x,y); } } return 0; }
|