#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define fbo find_by_order
#define ook order_of_key
typedef long long ll;
typedef pair<ll,ll> ii;
typedef vector<int> vi;
typedef long double ld;
typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> pbds;
typedef set<int>::iterator sit;
typedef map<int,int>::iterator mit;
typedef vector<int>::iterator vit;
typedef struct node
{
int prior,size;
int val;//value stored in the array
int sum;//whatever info you want to maintain in segtree for each node
int lazy;//whatever lazy update you want to do
bool rev;
bool rev_lazy;
struct node *l,*r;
}node;
typedef node* pnode;
node buffer[600001];
pnode tr;
pnode null;
int sz(pnode t)
{
return t?t->size:0;
}
void upd_sz(pnode t)
{
if(t)t->size=sz(t->l)+1+sz(t->r);
}
void lazy(pnode t)
{
if(!t)return;
t->val+=t->lazy;//operation of lazy
t->sum+=t->lazy*sz(t);
t->rev^=t->rev_lazy;
if(t->rev)
{
swap(t->l, t->r);
t->rev = 0;
}
if(t->l)
{
t->l->lazy+=t->lazy;//propagate lazy
t->l->rev_lazy^=t->rev_lazy;
}
if(t->r)
{
t->r->lazy+=t->lazy;
t->r->rev_lazy^=t->rev_lazy;
}
t->lazy=0; t->rev_lazy=0;
}
void reset(pnode t)
{
if(t)
{
t->sum = 0;//no need to reset lazy coz when we call this lazy would itself be propagated
t->rev = false;
}
}
void combine(pnode& t,pnode l,pnode r)
{//combining two ranges of segtree
if(!l || !r)return void(t = l?l:r);
t->sum = l->sum + r->sum;
}
void operation(pnode t)
{//operation of segtree
if(!t)return;
reset(t);//reset the value of current node assuming it now represents a single element of the array
lazy(t->l);lazy(t->r);//imp:propagate lazy before combining t->l,t->r;
combine(t,t->l,t);
combine(t,t,t->r);
}
void split(pnode t,pnode &l,pnode &r,int pos,int add=0)
{
if(!t)return void(l=r=NULL);
lazy(t);
int curr_pos = add + sz(t->l);
if(curr_pos<=pos)//element at pos goes to left subtree(l)
split(t->r,t->r,r,pos,curr_pos+1),l=t;
else
split(t->l,l,t->l,pos,add),r=t;
upd_sz(t);
operation(t);
}
void merge(pnode &t,pnode l,pnode r)
{ //l->leftarray,r->rightarray,t->resulting array
lazy(l);lazy(r);
if(!l || !r) t = l?l:r;
else if(l->prior>r->prior)merge(l->r,l->r,r),t=l;
else merge(r->l,l,r->l),t=r;
upd_sz(t);
operation(t);
}
node *ptr = buffer;
pnode init(int val)
{
pnode ret = ptr;
ret->prior=rand();ret->size=1;
ret->val=val;
ret->sum=0;ret->lazy=0;
ret->rev = false;
ptr++;
return ret;
}
int range_query(pnode t,int l,int r)
{//[l,r]
pnode L,mid,R;
split(t,L,mid,l-1);
split(mid,t,R,r-l);//note: r-l!!
int ans = (t->sum+t->val)%26;
//int ans = t->sum;
merge(mid,L,t);
merge(t,mid,R);
return ans;
}
void range_update(pnode t,int l,int r,int val)
{//[l,r]
pnode L,mid,R;
split(t,L,mid,l-1);
split(mid,t,R,r-l);//note: r-l!!
t->lazy+=val; //lazy_update
merge(mid,L,t);
merge(t,mid,R);
}
void range_reverse(pnode t,int l,int r)
{//[l,r]
pnode L,mid,R;
split(t,L,mid,l-1);
split(mid,t,R,r-l);//note: r-l!!
t->rev_lazy^=1; //lazy_update
merge(mid,L,t);
merge(t,mid,R);
}
char cycshift(char c, int x)
{
int z = c - 'a';
z += x;
z%=26;
return char(z+'a');
}
string s;
void initialize(int n)
{
tr = NULL;
for(int i = 0; i < n; i++)
{
pnode tmp = init(int(s[i]-'a'));
merge(tr, tr, tmp);
}
}
void upd(int l, int r, int pos) //split is 0-indexed
{
pnode L;
pnode R;
split(tr, L, R, l-1);
pnode mid;
split(R, mid, R, r-l);
merge(L, L, R);
pnode L2;
pnode R2;
split(L, L2, R2, pos);
merge(tr, L2, mid);
merge(tr, tr, R2);
}
int main()
{
ios_base::sync_with_stdio(0); cin.tie(0);
srand(123);
cin >> s;
initialize(int(s.length()));
int q; cin >> q;
while(q--)
{
int t, l, r;
cin>>t>>l>>r;
l--; r--;
if(t == 1)
{
int pos; cin >> pos; pos--;
upd(l, r, pos);
}
else if(t == 2)
{
int c; cin >> c;
c%=26;
range_update(tr, l, r, c);
}
else
{
range_reverse(tr, l, r);
}
}
for(int i = 0; i < s.length(); i++)
{
//cerr<<range_query(tr,i,i)<<'\n';
s[i] = char('a' + range_query(tr,i,i));
}
cout << s;
}
I2luY2x1ZGUgPGJpdHMvc3RkYysrLmg+CiNpbmNsdWRlIDxleHQvcGJfZHMvYXNzb2NfY29udGFpbmVyLmhwcD4KI2luY2x1ZGUgPGV4dC9wYl9kcy90cmVlX3BvbGljeS5ocHA+CiAKdXNpbmcgbmFtZXNwYWNlIHN0ZDsKdXNpbmcgbmFtZXNwYWNlIF9fZ251X3BiZHM7CiAKI2RlZmluZSBmaSBmaXJzdAojZGVmaW5lIHNlIHNlY29uZAojZGVmaW5lIG1wIG1ha2VfcGFpcgojZGVmaW5lIHBiIHB1c2hfYmFjawojZGVmaW5lIGZibyBmaW5kX2J5X29yZGVyCiNkZWZpbmUgb29rIG9yZGVyX29mX2tleQogCnR5cGVkZWYgbG9uZyBsb25nIGxsOwp0eXBlZGVmIHBhaXI8bGwsbGw+IGlpOwp0eXBlZGVmIHZlY3RvcjxpbnQ+IHZpOwp0eXBlZGVmIGxvbmcgZG91YmxlIGxkOyAKdHlwZWRlZiB0cmVlPGludCwgbnVsbF90eXBlLCBsZXNzPGludD4sIHJiX3RyZWVfdGFnLCB0cmVlX29yZGVyX3N0YXRpc3RpY3Nfbm9kZV91cGRhdGU+IHBiZHM7CnR5cGVkZWYgc2V0PGludD46Oml0ZXJhdG9yIHNpdDsKdHlwZWRlZiBtYXA8aW50LGludD46Oml0ZXJhdG9yIG1pdDsKdHlwZWRlZiB2ZWN0b3I8aW50Pjo6aXRlcmF0b3Igdml0OwogCnR5cGVkZWYgc3RydWN0IG5vZGUKewogICAgaW50IHByaW9yLHNpemU7CiAgICBpbnQgdmFsOy8vdmFsdWUgc3RvcmVkIGluIHRoZSBhcnJheQogICAgaW50IHN1bTsvL3doYXRldmVyIGluZm8geW91IHdhbnQgdG8gbWFpbnRhaW4gaW4gc2VndHJlZSBmb3IgZWFjaCBub2RlCiAgICBpbnQgbGF6eTsvL3doYXRldmVyIGxhenkgdXBkYXRlIHlvdSB3YW50IHRvIGRvCiAgICBib29sIHJldjsKICAgIGJvb2wgcmV2X2xhenk7CiAgICBzdHJ1Y3Qgbm9kZSAqbCwqcjsKfW5vZGU7CiAKdHlwZWRlZiBub2RlKiBwbm9kZTsKIApub2RlIGJ1ZmZlcls2MDAwMDFdOwpwbm9kZSB0cjsKcG5vZGUgbnVsbDsKIAppbnQgc3oocG5vZGUgdCkKewogICAgcmV0dXJuIHQ/dC0+c2l6ZTowOwp9CiAKdm9pZCB1cGRfc3oocG5vZGUgdCkKewogICAgaWYodCl0LT5zaXplPXN6KHQtPmwpKzErc3oodC0+cik7Cn0KIAp2b2lkIGxhenkocG5vZGUgdCkKewogICAgaWYoIXQpcmV0dXJuOwogICAgdC0+dmFsKz10LT5sYXp5Oy8vb3BlcmF0aW9uIG9mIGxhenkKICAgIHQtPnN1bSs9dC0+bGF6eSpzeih0KTsKICAgIHQtPnJldl49dC0+cmV2X2xhenk7CiAgICBpZih0LT5yZXYpCiAgICB7CgkJc3dhcCh0LT5sLCB0LT5yKTsKCQl0LT5yZXYgPSAwOwoJfQogICAgaWYodC0+bCkKICAgIHsKCQl0LT5sLT5sYXp5Kz10LT5sYXp5Oy8vcHJvcGFnYXRlIGxhenkKCQl0LT5sLT5yZXZfbGF6eV49dC0+cmV2X2xhenk7Cgl9CiAgICBpZih0LT5yKQogICAgewoJCXQtPnItPmxhenkrPXQtPmxhenk7CgkJdC0+ci0+cmV2X2xhenlePXQtPnJldl9sYXp5OwoJfQogICAgdC0+bGF6eT0wOyB0LT5yZXZfbGF6eT0wOwp9CiAKdm9pZCByZXNldChwbm9kZSB0KQp7CiAgICBpZih0KQogICAgewoJCXQtPnN1bSA9IDA7Ly9ubyBuZWVkIHRvIHJlc2V0IGxhenkgY296IHdoZW4gd2UgY2FsbCB0aGlzIGxhenkgd291bGQgaXRzZWxmIGJlIHByb3BhZ2F0ZWQKCQl0LT5yZXYgPSBmYWxzZTsKCX0KfQogCnZvaWQgY29tYmluZShwbm9kZSYgdCxwbm9kZSBsLHBub2RlIHIpCnsvL2NvbWJpbmluZyB0d28gcmFuZ2VzIG9mIHNlZ3RyZWUKICAgIGlmKCFsIHx8ICFyKXJldHVybiB2b2lkKHQgPSBsP2w6cik7CiAgICB0LT5zdW0gPSBsLT5zdW0gKyByLT5zdW07Cn0KIAp2b2lkIG9wZXJhdGlvbihwbm9kZSB0KQp7Ly9vcGVyYXRpb24gb2Ygc2VndHJlZQogICAgaWYoIXQpcmV0dXJuOwogICAgcmVzZXQodCk7Ly9yZXNldCB0aGUgdmFsdWUgb2YgY3VycmVudCBub2RlIGFzc3VtaW5nIGl0IG5vdyByZXByZXNlbnRzIGEgc2luZ2xlIGVsZW1lbnQgb2YgdGhlIGFycmF5CiAgICBsYXp5KHQtPmwpO2xhenkodC0+cik7Ly9pbXA6cHJvcGFnYXRlIGxhenkgYmVmb3JlIGNvbWJpbmluZyB0LT5sLHQtPnI7CiAgICBjb21iaW5lKHQsdC0+bCx0KTsKICAgIGNvbWJpbmUodCx0LHQtPnIpOwp9CiAKdm9pZCBzcGxpdChwbm9kZSB0LHBub2RlICZsLHBub2RlICZyLGludCBwb3MsaW50IGFkZD0wKQp7CiAgICBpZighdClyZXR1cm4gdm9pZChsPXI9TlVMTCk7CiAgICBsYXp5KHQpOwogICAgaW50IGN1cnJfcG9zID0gYWRkICsgc3oodC0+bCk7CiAgICBpZihjdXJyX3Bvczw9cG9zKS8vZWxlbWVudCBhdCBwb3MgZ29lcyB0byBsZWZ0IHN1YnRyZWUobCkKICAgICAgICBzcGxpdCh0LT5yLHQtPnIscixwb3MsY3Vycl9wb3MrMSksbD10OwogICAgZWxzZSAKICAgICAgICBzcGxpdCh0LT5sLGwsdC0+bCxwb3MsYWRkKSxyPXQ7CiAgICB1cGRfc3oodCk7CiAgICBvcGVyYXRpb24odCk7Cn0KIAp2b2lkIG1lcmdlKHBub2RlICZ0LHBub2RlIGwscG5vZGUgcikKeyAvL2wtPmxlZnRhcnJheSxyLT5yaWdodGFycmF5LHQtPnJlc3VsdGluZyBhcnJheQogICAgbGF6eShsKTtsYXp5KHIpOwogICAgaWYoIWwgfHwgIXIpIHQgPSBsP2w6cjsKICAgIGVsc2UgaWYobC0+cHJpb3I+ci0+cHJpb3IpbWVyZ2UobC0+cixsLT5yLHIpLHQ9bDsKICAgIGVsc2UgICAgbWVyZ2Uoci0+bCxsLHItPmwpLHQ9cjsKICAgIHVwZF9zeih0KTsKICAgIG9wZXJhdGlvbih0KTsKfQogCm5vZGUgKnB0ciA9IGJ1ZmZlcjsKIApwbm9kZSBpbml0KGludCB2YWwpCnsKICAgIHBub2RlIHJldCA9IHB0cjsKICAgIHJldC0+cHJpb3I9cmFuZCgpO3JldC0+c2l6ZT0xOwogICAgcmV0LT52YWw9dmFsOwogICAgcmV0LT5zdW09MDtyZXQtPmxhenk9MDsKICAgIHJldC0+cmV2ID0gZmFsc2U7CiAgICBwdHIrKzsKICAgIHJldHVybiByZXQ7Cn0KIAppbnQgcmFuZ2VfcXVlcnkocG5vZGUgdCxpbnQgbCxpbnQgcikKey8vW2wscl0KICAgIHBub2RlIEwsbWlkLFI7CiAgICBzcGxpdCh0LEwsbWlkLGwtMSk7CiAgICBzcGxpdChtaWQsdCxSLHItbCk7Ly9ub3RlOiByLWwhIQogICAgaW50IGFucyA9ICh0LT5zdW0rdC0+dmFsKSUyNjsKICAgIC8vaW50IGFucyA9IHQtPnN1bTsKICAgIG1lcmdlKG1pZCxMLHQpOwogICAgbWVyZ2UodCxtaWQsUik7CiAgICByZXR1cm4gYW5zOwp9CiAKdm9pZCByYW5nZV91cGRhdGUocG5vZGUgdCxpbnQgbCxpbnQgcixpbnQgdmFsKQp7Ly9bbCxyXQogICAgcG5vZGUgTCxtaWQsUjsKICAgIHNwbGl0KHQsTCxtaWQsbC0xKTsKICAgIHNwbGl0KG1pZCx0LFIsci1sKTsvL25vdGU6IHItbCEhCiAgICB0LT5sYXp5Kz12YWw7IC8vbGF6eV91cGRhdGUKICAgIG1lcmdlKG1pZCxMLHQpOwogICAgbWVyZ2UodCxtaWQsUik7Cn0KIAp2b2lkIHJhbmdlX3JldmVyc2UocG5vZGUgdCxpbnQgbCxpbnQgcikKey8vW2wscl0KICAgIHBub2RlIEwsbWlkLFI7CiAgICBzcGxpdCh0LEwsbWlkLGwtMSk7CiAgICBzcGxpdChtaWQsdCxSLHItbCk7Ly9ub3RlOiByLWwhIQogICAgdC0+cmV2X2xhenlePTE7IC8vbGF6eV91cGRhdGUKICAgIG1lcmdlKG1pZCxMLHQpOwogICAgbWVyZ2UodCxtaWQsUik7Cn0KIApjaGFyIGN5Y3NoaWZ0KGNoYXIgYywgaW50IHgpCnsKCWludCB6ID0gYyAtICdhJzsKCXogKz0geDsKCXolPTI2OwoJcmV0dXJuIGNoYXIoeisnYScpOwp9CiAKc3RyaW5nIHM7CiAKdm9pZCBpbml0aWFsaXplKGludCBuKQp7Cgl0ciA9IE5VTEw7Cglmb3IoaW50IGkgPSAwOyBpIDwgbjsgaSsrKQoJewoJCXBub2RlIHRtcCA9IGluaXQoaW50KHNbaV0tJ2EnKSk7CgkgICAgbWVyZ2UodHIsIHRyLCB0bXApOwoJfQp9CiAKdm9pZCB1cGQoaW50IGwsIGludCByLCBpbnQgcG9zKSAvL3NwbGl0IGlzIDAtaW5kZXhlZAp7Cglwbm9kZSBMOwoJcG5vZGUgUjsKCXNwbGl0KHRyLCBMLCBSLCBsLTEpOwoJcG5vZGUgbWlkOwoJc3BsaXQoUiwgbWlkLCBSLCByLWwpOwoJbWVyZ2UoTCwgTCwgUik7Cglwbm9kZSBMMjsKCXBub2RlIFIyOwoJc3BsaXQoTCwgTDIsIFIyLCBwb3MpOwoJbWVyZ2UodHIsIEwyLCBtaWQpOwoJbWVyZ2UodHIsIHRyLCBSMik7Cn0KIAppbnQgbWFpbigpCnsKCWlvc19iYXNlOjpzeW5jX3dpdGhfc3RkaW8oMCk7IGNpbi50aWUoMCk7CglzcmFuZCgxMjMpOwoJY2luID4+IHM7Cglpbml0aWFsaXplKGludChzLmxlbmd0aCgpKSk7CglpbnQgcTsgY2luID4+IHE7Cgl3aGlsZShxLS0pCgl7CgkJaW50IHQsIGwsIHI7CgkJY2luPj50Pj5sPj5yOwoJCWwtLTsgci0tOwoJCWlmKHQgPT0gMSkKCQl7CgkJCWludCBwb3M7IGNpbiA+PiBwb3M7IHBvcy0tOwoJCQl1cGQobCwgciwgcG9zKTsKCQl9CgkJZWxzZSBpZih0ID09IDIpCgkJewoJCQlpbnQgYzsgY2luID4+IGM7CgkJCWMlPTI2OwoJCQlyYW5nZV91cGRhdGUodHIsIGwsIHIsIGMpOwoJCX0KCQllbHNlCgkJewoJCQlyYW5nZV9yZXZlcnNlKHRyLCBsLCByKTsKCQl9Cgl9Cglmb3IoaW50IGkgPSAwOyBpIDwgcy5sZW5ndGgoKTsgaSsrKQoJewoJCS8vY2Vycjw8cmFuZ2VfcXVlcnkodHIsaSxpKTw8J1xuJzsKCQlzW2ldID0gY2hhcignYScgKyByYW5nZV9xdWVyeSh0cixpLGkpKTsKCX0KCWNvdXQgPDwgczsKfQog