/*input 3 5 aba 2 0 2 2 0 0 2 1 2 1 0 1 1 2 0 2 */ #include #include using namespace std; long long mod=1e9+7; typedef long long unsigned llu; typedef long long int lld; typedef long ld; #define rep(i,a,n) for(long long int i = (a); i <= (n); ++i) #define repI(i,a,n) for(int i = (a); i <= (n); ++i) #define repD(i,a,n) for(long long int i = (a); i >= (n); --i) #define repDI(i,a,n) for(int i = (a); i >= (n); --i) #define pb push_back #define mp make_pair #define ff first #define ss second #define sc(a) scanf("%lld",&a) #define sc2(a,b) scanf("%lld%lld",&a,&b) #define sc3(a,b,c) scanf("%lld%lld%lld",&a,&b,&c) #define scd(a) scanf("%d",&a) #define scd2(a,b) scanf("%d%d",&a,&b) #define scd3(a,b,c) scanf("%d%d%d",&a,&b,&c) #define scf(a) scanf("%lf",&a) #define scf2(a,b) scanf("%lf%lf",&a,&b) #define scf3(a,b,c) scanf("%lf%lf%lf",&a,&b,&c) #define prL(a) printf("%lld\n",a) #define prS(a) printf("%lld ",a) #define prdL(a) printf("%d\n",a) #define prdS(a) printf("%d ",a) #define prfL(a) printf("%lf\n",a) #define prfS(a) printf("%lf ",a) #define popcount __builtin_popcountll #define swap(a,b,t) t=a;a=b;b=t typedef pair PA; #define lim 200003 #define lim2 3003 inline lld sqr(lld x) { return x * x; } // map,lld> M; // map M,Mn; // map::iterator it; // set::iterator it; // std::ios::sync_with_stdio(false); // string S[lim],T[lim],Q[lim]; // multiset S; // set H,V; // string S[lim]; // vector V[lim]; // vector IN[lim]; // lld dp[3003][3003]; // lld A[lim],dp1[lim],dp2[lim],P[lim]; // bool dp[1002][12][12]; // priority_queue Q; // double X[lim],Y[lim],C[lim]; // lld A[lim],B[lim],dp[2002][2002]; // lld P[lim],Q[lim]; // std::vector V; // lld P[lim],Q[lim],R[lim]; // char S[lim]; // double dp[1<<18]; // lld countV=0,op; lld one,zero,ansR,numNodes; typedef struct node{ long long lazy; long long Freq[26]; }treeNode; string A; treeNode M[lim<<2]; treeNode combineNodes(treeNode p1,treeNode p2){ treeNode pAns; // pAns.sum=p1.sum+p2.sum; for(int i=0;i<26;i++) pAns.Freq[i]=p1.Freq[i]+p2.Freq[i]; pAns.lazy=0; return pAns; } treeNode updateNode(int st,int end,treeNode p1,long long val){ treeNode pAns; // pAns.sum=p1.sum+(end-st+1)*val; for(int i=0;i<26;i++) pAns.Freq[(i+val)%26]=p1.Freq[i]; pAns.lazy=(p1.lazy+val)%26; return pAns; } void shift(int st,int end,int ind){ int mid,a,b; mid=st+(end-st)/2; a=(ind<<1)+1; b=(ind<<1)+2; M[a]=updateNode(st,mid,M[a],M[ind].lazy); M[b]=updateNode(mid+1,end,M[b],M[ind].lazy); M[ind].lazy=0; } void buildTree(int st,int end,int ind){ if(st==end){ // M[ind].sum=A[st]; for(int i=0;i<26;i++) M[ind].Freq[i]=0; M[ind].Freq[A[st]-'a']=1; M[ind].lazy=0; return ; } int mid,a,b; mid=st+(end-st)/2; a=(ind<<1)+1; b=(ind<<1)+2; buildTree(st,mid,a); buildTree(mid+1,end,b); M[ind]=combineNodes(M[a],M[b]); } void updateTree(int st,int end,int ind,int l,int r,long long val){ // printf("st=%d end=%d ind=%d l=%d r=%d val=%lld\n",st,end,ind,l,r,val ); if(st==l && end==r){ M[ind]=updateNode(l,r,M[ind],val); return ; } int mid,a,b; shift(st,end,ind); mid=st+(end-st)/2; a=(ind<<1)+1; b=(ind<<1)+2; if(r<=mid) updateTree(st,mid,a,l,r,val); else if(l>mid) updateTree(mid+1,end,b,l,r,val); else{ updateTree(st,mid,a,l,mid,val); updateTree(mid+1,end,b,mid+1,r,val); } M[ind]=combineNodes(M[a],M[b]); } treeNode query(int st,int end,int ind,int l,int r){ if(st==l && end==r) return M[ind]; int mid; treeNode p1,p2; shift(st,end,ind); mid=st+(end-st)/2; if(r<=mid) return query(st,mid,(ind<<1)+1,l,r); if(l>mid) return query(mid+1,end,(ind<<1)+2,l,r); p1=query(st,mid,(ind<<1)+1,l,mid); p2=query(mid+1,end,(ind<<1)+2,mid+1,r); return combineNodes(p1,p2); } lld powP(lld a,lld b){ if(b==0) return 1%mod; lld k; k=powP(a,b/2); k=k*k%mod; if(b%2==0) return k; else return a*k%mod; } lld answerFunc(vector &freq){ lld answer1=1; lld count1=0; rep(i,0,freq.size()-1){ if(freq[i]!=0){ count1++; answer1=(answer1*powP(2,freq[i]-1))%mod; } } answer1=(answer1*(count1+1))%mod; return (answer1-1+mod)%mod; } int main(){ // std::ios::sync_with_stdio(false); lld T,i,j,h,l,r,k,s,a,b,c,d,n,m,w,x,y,v,z,t,p,q,curr,prev,sum,ans,pos,val,countA,secondMin,indicator; sc2(n,q); // rep(i,0,n-1) A[i]=0; cin>>A; buildTree(0,n-1,0); while(q--){ sc3(k,l,r); // l--;r--; if(k==1){ sc(v); updateTree(0,n-1,0,l,r,v); } else{ treeNode TN=query(0,n-1,0,l,r); vector Fro(26,0); for(int i=0;i<26;i++) Fro[i]=TN.Freq[i]; // rep(i,0,25) printf("%lld(%c) ",Fro[i],int(i)+'a' ); // printf("\n"); prL(answerFunc(Fro)); } } return 0; }