/*********** [ scopeInfinity ] ******************/ #include using namespace std; typedef long long ll; typedef std::vector vll; #define mp make_pair #define pb(x) push_back((x)) ll MOD = 1e9+7; ll INF = LLONG_MAX; vector &split(const std::string &s, char delim, vector &e) { stringstream ss(s); string item; while(getline(ss, item, delim)) e.push_back(item); return e; } ll Pow(ll a ,int b ,int Mo){ ll ans = 1; for (; b; b >>= 1, a = a * a % Mo) if (b&1) ans = ans * a % Mo; return ans; } struct Node { ll val[26]; Node() { for (int i = 0; i < 26; ++i) { val[i]=0; } } Node(int v) { for (int i = 0; i < 26; ++i) { val[i]=0; } val[v]=1; } }; namespace Lazy { //Non leaf from 1 -> size-1 typedef Node TYPE; typedef int TYPE_AUX; const TYPE T_ZERO = Node(); const TYPE_AUX TA_ZERO = 0; #define getEnc(index) (1< 2*size-1 //1< v_height; std::vector data; std::vector data_aux; //#define mergeVal(l,r) (((l)+(r))%MOD) Node mergeVal(Node &l,Node &r) { Node n; for (int i = 0; i < 26; ++i) { n.val[i]=l.val[i]+r.val[i]; } return n; } // Apply toapply on data[index] void apply(int index, TYPE_AUX toapply) { Node n = data[index]; for (int i = 0; i < 26; ++i) { data[index].val[(i+toapply)%26]=n.val[i]; } data_aux[index]=(data_aux[index]+toapply)%26; } void pushdown(int index) { TYPE_AUX &toapply = data_aux[index]; if(toapply == 0) return ; if(index>=1)height++; size = 1<(2*size,T_ZERO); data_aux = std::vector(2*size,TA_ZERO); v_height = std::vector(2*size); int level = 0,lev_c=0; for(int i=1;i<2*size;i++) { if(lev_c == 1< 0; --i) fixup(i); } //QueryIndex,View index, Actual Index TYPE squery(int query_l,int query_r,int l,int r,int node) { pushdown(node); if(rquery_r || l>r) return T_ZERO; if(query_l<=l && r<=query_r) { return data[node]; } TYPE dleft = squery(query_l,query_r,l,(l+r)/2,node<<1); TYPE dright = squery(query_l,query_r,(l+r)/2 +1 ,r,node<<1 | 1); return mergeVal(dleft,dright); } //Incl. left and right Node query(int left,int right) { return squery(left,right,0,size-1,1); } void stask(int query_l,int query_r,int l,int r,int node,int val,int type) { if(rquery_r || l>r) return ; pushdown(node); if(query_l<=l && r<=query_r) { apply(node,val%26); return ; } stask(query_l,query_r,l,(l+r)/2,node<<1,val,type); stask(query_l,query_r,(l+r)/2+1,r,node<<1 | 1,val,type); fixup(node); return ; } //Incl. left and..right //type == 0 , increment void task(int left,int right,int val,int type) { stask(left,right,0,size-1,1,val,type); } } ll MAX = 1e5+10; std::vector p2(MAX,1); long solve() { ll N,Q; cin>>N>>Q; string s; cin>>s; Lazy::build(s); while(Q--) { int t,l,r,k; cin>>t>>l>>r; if(t==1) { cin>>k; Lazy::task(l,r,k,0); } else { Node n = Lazy::query(l,r); // ///ALOTTTTTTTTTTT // for (int i = 0; i < 26; ++i) // { // cout<<(char)(i+'a')<<"\t"< se(26,0),so(26,0); for (int i = 0; i < 26; ++i) if(n.val[i]>0){ ll x= n.val[i]; se[i]=p2[x-1]; //if(x%2) so[i]=p2[x-1]; // cerr<<"Char "<<(char)(i+'a')<<" > "<0){ now=(now*se[i])%MOD; } //cerr<<"Subset incld 0size EVEN=> "<0){ ll w = so[i]; for (int j = 0; j < 26; ++j) if(i!=j && se[j]>0) { w=(w*se[j])%MOD; } // cerr<<"Subset incld ODD "<<(char)(i+'a')<<" => "<