Problem:
String Crossing
Problem
N
個の文字列{
S
1
,
S
2
, ...,
S
N
} が与えられる。
続いて
Q
個のクエリが与えられる。
クエリの種類は以下の2つである。
a
,
b
,
c
,
d
が入力され
S
a
の
b
文字目からの substring を
S
c
の
d
-1文字までの substring の後に繋げる。これを新しい
S
c
とする。
元の
S
c
の
d
文字目からの substring を
S
a
の
b
-1文字までの substring の後に繋げる。これを新しい
S
a
とする。
a
,
b
,
c
が入力され
S
a
の
b
文字目を
c
に変更する。
例えば
S
1
="abcd",
S
2
="efgh"があり
クエリの種類が1で
a
=1,
b
=2,
c
=2,
d
=3のとき
a  - -> bcd
    X
ef - -> gh
S
1
="agh",
S
2
="efbcd"となる。
全てのクエリを処理した後の文字列
S
1
から
S
N
を全て出力せよ。
Input
入力は以下の形式で与えられる。
N
Q
S
1
S
2
...
S
N
query
1
query
2
...
query
Q
各
query
は次のいずれかである。
1
a
b
c
d
or
2
a
b
c
Constraints
1 ≤
N
≤ 10
5
1 ≤
Q
≤ 10
5
N
個の文字列の長さの合計は2×10
6
を越えない。
文字列
S
i
は全て英小文字であることが保証される。
クエリの種類が1のとき
a
≠
c
1 ≤
b
≤ |
S
a
|
1 ≤
d
≤ |
S
c
|
クエリの種類が2のとき
1 ≤
b
≤ |
S
a
|
c
は英小文字であることが保証される。
高速な入出力を推奨する。
Output
各クエリを処理した後の文字列を
S
1
から
S
N
まで1行ずつ出力せよ。
S
1
S
2
...
S
N
Sample Input 1
2 1
abcd
efgh
1 1 2 2 3
Sample Output 1
agh
efbcd
Sample Input 2
2 3
abcd
efgh
1 1 2 2 3
2 1 3 x
2 2 4 x
Sample Output 2
agx
efbxd
Sample Input 3
10 10
sjcvpauokb
fmeaowomscy
sepeqqfcosrjmonfsv
zapc
aromazjzqoeiqswvcaf
clifpa
dusudcz
qeqdzdtdzlkhc
gkpsjvdvadmf
xrtyxnkolluagwxp
1 4 4 6 3
1 7 1 8 1
2 2 6 o
1 4 4 3 7
2 1 2 i
1 6 3 3 2
1 6 5 1 9
2 10 9 j
1 2 2 7 3
2 3 2 b
Sample Output 3
sicvpauoeqqifpa
fqdzdtdzlkhc
sb
zapfcosrjmonfsv
aromazjzqoeiqswvcaf
clepkb
qemeaooomscy
dusudcz
gkpsjvdvadmf
xrtyxnkojluagwxp

Submitted solutions:

code_snippet: // AOJ #1571 String Crossing
// 2025.4.5

#include <bits/stdc++.h>
using namespace std;
#include <ext/rope>
using namespace __gnu_cxx;

#define gc() getchar_unlocked()
#define pc(c) putchar_unlocked(c)

int Cin() {  // 整数の入力
	int n = 0; int c = gc();
	do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
	return n;
}

char temp[2000005];
string Cins() { // 文字列の入力　スペース以下の文字で入力終了
    char *s = temp;
	do *s = gc();
	while (*s++ > ' ');
	*(s-1) = 0;
    string input(temp); // 文字配列からstringを作成
    return input;
}

int main(){
    int n = Cin(), q = Cin();
    rope<char>* A = new rope<char>[n];
    for(int i = 0; i < n; i++){
        string s = Cins();
        A[i] = rope<char>(s.c_str());
    }

    while(q--){
        int t = gc() & 0xf; gc();
        if(t == 1){
            int a = Cin()-1, b = Cin()-1, c = Cin()-1, d = Cin()-1;
            rope<char> L_a = A[a].substr(0, b);
            rope<char> R_a = A[a].substr(b, A[a].size() - b);
            rope<char> L_c = A[c].substr(0, d);
            rope<char> R_c = A[c].substr(d, A[c].size() - d);
            A[c] = L_c + R_a;
            A[a] = L_a + R_c;
        } else {
            int a = Cin()-1, b = Cin()-1;
            char ch = gc(); gc();
            A[a].replace(b, 1, &ch, 1);
        }
    }
    for (int i = 0; i < n; i++){
        for (int j = 0; j < A[i].size(); j++) pc(A[i][j]);
        pc('\n');
    }
//  delete[] A;
    return 0;
}
accuracy: 1
time_ms: 660
memory_kb: 47016
final_rank: 3

code_snippet: // AOJ #1571 String Crossing
// 2025.4.5

#include <bits/stdc++.h>
using namespace std;
#include <ext/rope>
using namespace __gnu_cxx;

#define gc() getchar_unlocked()
#define pc(c) putchar_unlocked(c)

int Cin() {  // 整数の入力
	int n = 0; int c = gc();
	do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
	return n;
}

char temp[2000005];
string Cins() { // 文字列の入力　スペース以下の文字で入力終了
    char *s = temp;
	do *s = gc();
	while (*s++ > ' ');
	*(s-1) = 0;
    string input(temp); // 文字配列からstringを作成
    return input;
}

int main(){
    int n = Cin(), q = Cin();
    rope<char>* A = new rope<char>[n];
    for (int i = 0; i < n; i++){
        string s = Cins();
        A[i] = rope<char>(s.c_str());
    }

    while(q--){
        int t = gc() & 0xf; gc();
        if(t == 1){
            int a = Cin()-1, b = Cin()-1, c = Cin()-1, d = Cin()-1;
            rope<char> X = A[a].substr(b, A[a].size() - b);
            rope<char> Y = A[c].substr(d, A[c].size() - d);
            A[a].erase(b, A[a].size() - b);
            A[c].erase(d, A[c].size() - d);
            A[a].append(Y);
            A[c].append(X);
        } else {
            int a = Cin()-1, b = Cin()-1;
            char ch = gc(); gc();
            A[a].replace(b, 1, &ch, 1);
        }
    }

    for (int i = 0; i < n; i++){
        for (int j = 0; j < A[i].size(); j++) pc(A[i][j]);
        pc('\n');
    }
//  delete[] A;
    return 0;
}
accuracy: 1
time_ms: 680
memory_kb: 46992
final_rank: 4

code_snippet: // AOJ #1571 String Crossing
// 2025.4.5

#include <bits/stdc++.h>
using namespace std;
#include <ext/rope>
using namespace __gnu_cxx;

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);

    int n, q;
    cin >> n >> q;
    rope<char>* A = new rope<char>[n];
    for(int i = 0; i < n; i++){
        string s;
        cin >> s;
        A[i] = rope<char>(s.c_str());
    }

    while(q--){
        int t;
        cin >> t;
        if(t == 1){
            int a, b, c, d;
            cin >> a >> b >> c >> d;
            a--; c--;
            rope<char> L_a = A[a].substr(0, b-1);
            rope<char> R_a = A[a].substr(b-1, A[a].size() - (b-1));
            rope<char> L_c = A[c].substr(0, d-1);
            rope<char> R_c = A[c].substr(d-1, A[c].size() - (d-1));
            A[c] = L_c + R_a;
            A[a] = L_a + R_c;
        } else {
            int a, b;
            char ch;
            cin >> a >> b >> ch;
            a--;
            A[a].replace(b-1, 1, &ch, 1);
        }
    }
    for (int i = 0; i < n; i++){
        for (int j = 0; j < A[i].size(); j++) cout << A[i][j];
        cout << endl;
    }
//  delete[] A;
    return 0;
}
accuracy: 1
time_ms: 710
memory_kb: 46044
final_rank: 5

code_snippet: #include <bits/stdc++.h>
#define MOD 1000000007LL
using namespace std;
typedef long long ll;
typedef pair<int,int> P;

unsigned int y=11451419;

int rand_int(int l=0,int r=11451419){
	y=y^(y<<13);
	y=y^(y>>17);
	y=y^(y<<5);
	return y%(r-l+1)+l;
}


template<class T>
struct treap{
	struct node_t{
		T val; // 値
		node_t *lch, *rch;
		int pri; // 優先度
		int cnt; // 部分木のサイズ
		T sum; // 部分木の値の和
		node_t(T v, int p):val(v), pri(p), cnt(1), sum(v){
			lch = rch = NULL;
		}
	};
	node_t *root;
	treap():root(NULL){}

	int count(node_t *t){ return t ? t->cnt : 0; }
	T sum(node_t *t){ return t ? t->sum : 0; }
	node_t *update(node_t *t){
    	t->cnt = count(t->lch) + count(t->rch) + 1;
    	t->sum = sum(t->lch) + sum(t->rch) + t->val;
    	return t;
    }

    //木rを木lの後に追加する
    node_t *merge(node_t *l, node_t *r){
    	if(!l || !r) return l?l:r;
        if(l->pri > r->pri){ // 左の部分木の根のほうが優先度が高い
        	l->rch = merge(l->rch, r);
        	return update(l);
        }else{
        	r->lch = merge(l, r->lch);
        	return update(r);
        }
    }

    pair<node_t*, node_t*> split(node_t *t, int k){ // [0,k), [k,n)
    	if(!t) return {NULL,NULL};
    	if(k <= count(t->lch)){
    		pair<node_t*,node_t*> s = split(t->lch,k);
    		t->lch = s.second;
    		return {s.first, update(t)};
    	}else{
    		pair<node_t*,node_t*> s = split(t->rch, k-count(t->lch)-1);
    		t->rch = s.first;
    		return {update(t), s.second};
    	}
    }

    node_t *insert(node_t *t, int k, T val, int pri){
    	pair<node_t*,node_t*> s = split(t,k);
    	t = merge(s.first, new node_t(val,pri));
    	t = merge(t, s.second);
    	return update(t);
    }

   	// eraseによってsiz=0になるとバグって使えなくなるので注意
    node_t *erase(node_t *t, int k){
    	pair<node_t*,node_t*> s2 = split(t,k+1);
    	pair<node_t*,node_t*> s1 = split(s2.first, k);
    	t = merge(s1.first, s2.second);
    	return update(t);
    }

    node_t *find(node_t *t, int k){
    	int c = count(t->lch);
    	if(k < c) return find(t->lch,k);
    	if(k == c) return t;
    	return find(t->rch, k-c-1);
    }

    void insert(int k, T val){ root = insert(root, k, val, rand_int()); }
    void erase(int k){ root = erase(root, k); }
    node_t *find(int k){ return find(root,k); }

};

treap<char> tr[100005];
int n,q;

int main(void){
	scanf("%d%d",&n,&q);
	for(int i=0;i<n;i++){
		string str;
		cin >> str;
		for(int j=0;j<str.size();j++){
			tr[i].insert(j,str[j]);
		}
	}
	for(int i=0;i<q;i++){
		int type;
		scanf("%d",&type);
		if(type==1){
			int a,b,c,d;
			scanf("%d%d%d%d",&a,&b,&c,&d);
			a--;
			b--;
			c--;
			d--;
			auto sa=tr[a].split(tr[a].root,b);
			auto sc=tr[c].split(tr[c].root,d);
			tr[a].root=tr[a].merge(sa.first,sc.second);
			tr[c].root=tr[c].merge(sc.first,sa.second);
		}else{
			int a,b;
			char c;
			scanf("%d%d%*c%c%*c",&a,&b,&c);
			a--;
			b--;
			tr[a].insert(b,c);
			tr[a].erase(b+1);
		}
	}
	for(int i=0;i<n;i++){
		int v=tr[i].count(tr[i].root);
		for(int j=0;j<v;j++){
			printf("%c",tr[i].find(j)->val);
		}
		printf("\n");
	}
	return 0;
}
accuracy: 1
time_ms: 750
memory_kb: 102460
final_rank: 9

code_snippet: #include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll> P;

#define fi first
#define se second
#define repl(i,a,b) for(ll i=(ll)(a);i<(ll)(b);i++)
#define rep(i,n) repl(i,0,n)
#define all(x) (x).begin(),(x).end()
#define dbg(x) cout<<#x"="<<x<<endl
#define mmax(x,y) (x>y?x:y)
#define mmin(x,y) (x<y?x:y)
#define maxch(x,y) x=mmax(x,y)
#define minch(x,y) x=mmin(x,y)
#define uni(x) x.erase(unique(all(x)),x.end())
#define exist(x,y) (find(all(x),y)!=x.end())
#define bcnt __builtin_popcount

template<class T>
struct treap{
    struct node_t{
        T val; // 値
        node_t *lch, *rch;
        int pri; // 優先度
        int cnt; // 部分木のサイズ
        // T sum; // 部分木の値の和
        // T mn; // 部分木の最小値

        node_t(T v, int p):val(v), pri(p), cnt(1){
            lch = rch = NULL;
        }
    };

    const T INF = 19191919; // TODO:initialize
    mt19937 mt;
    node_t *root;
    treap():root(NULL){
        const int seed = 364364;
        mt = mt19937(seed);
    }

    int count(node_t *t){ return t ? t->cnt : 0; }
    // T sum(node_t *t){ return t ? t->sum : 0; }
    // T min(node_t *t){ return t ? t->mn : INF; }

    node_t *update(node_t *t){
        t->cnt = count(t->lch) + count(t->rch) + 1;
        // t->sum = sum(t->lch) + sum(t->rch) + t->val;
        // t->mn = std::min({min(t->lch), min(t->rch), t->val});
        return t;
    }

    node_t *merge(node_t *l, node_t *r){
        if(!l || !r) return l?l:r;

        if(l->pri > r->pri){ // 左の部分木の根のほうが優先度が高い
            l->rch = merge(l->rch, r);
            return update(l);
        }
        else{
            r->lch = merge(l, r->lch);
            return update(r);
        }
    }

    pair<node_t*, node_t*> split(node_t *t, int k){ // [0,k), [k,n)
        if(!t) return {NULL,NULL};
        if(k <= count(t->lch)){
            auto s = split(t->lch,k);
            t->lch = s.second;
            return {s.first, update(t)};
        }
        else{
            auto s = split(t->rch, k-count(t->lch)-1);
            t->rch = s.first;
            return {update(t), s.second};
        }
    }

    node_t *insert(node_t *t, int k, T val, int pri){
        auto s = split(t,k);
        t = merge(s.first, new node_t(val,pri));
        t = merge(t, s.second);
        return update(t);
    }

    node_t *erase(node_t *t, int k){
        auto s2 = split(t,k+1);
        auto s1 = split(s2.first, k);
        t = merge(s1.first, s2.second);
        return update(t);
    }

    node_t *find(node_t *t, int k){
        int c = count(t->lch);
        if(k < c) return find(t->lch,k);
        if(k == c) return t;
        return find(t->rch, k-c-1);
    }

    void insert(int k, T val){ root = insert(root, k, val, mt()); }
    void erase(int k){ root = erase(root, k); }
    node_t *find(int k){ return find(root,k); }

    // // circular shift (右端の値が左端に来て、それ以外が右に1つずつシフト)
    // void shift(int l, int r){
    //     if(r-l==1) return;
    //     assert(l<r);
    //     auto sr = split(root, r);
    //     auto sl = split(sr.first, l);
    //     auto lr = split(sl.second, r-l-1);
    //     root = merge(merge(sl.first, merge(lr.second, lr.first)), sr.second);
    // }

    // // [l,r)
    // T min(int l, int r){
    //     assert(l<r);
    //     auto sr = split(root, r);
    //     auto sl = split(sr.first, l);
    //     auto lr = sl.second;
    //     T ret = min(lr);
    //     // 元に戻す
    //     root = merge(merge(sl.first, lr), sr.second);
    //     return ret;
    // }
};

int N,Q;
vector<treap<int> > ts;

int main(){
  scanf("%d %d ",&N,&Q);
  ts.resize(N);
  rep(i,N){
    ts[i].insert(0,-1);
    int j=1;
    while(1){
      char c;
      scanf("%c",&c);
      if(c=='\n')break;
      ts[i].insert(j++,c-'a');
    }
  }

  while(Q--){
    int tp;
    scanf(" %d",&tp);
    if(tp==1){
      int a,b,c,d;
      scanf(" %d %d %d %d",&a,&b,&c,&d);
      a--;c--;

      auto pa=ts[0].split(ts[a].root,b);
      auto pc=ts[0].split(ts[c].root,d);

      ts[a].root=ts[0].merge(pa.fi,pc.se);
      ts[c].root=ts[0].merge(pc.fi,pa.se);
    }else{
      int a,b;
      char c;
      scanf(" %d %d %c",&a,&b,&c);
      a--;

      ts[a].erase(b);
      ts[a].insert(b,c-'a');
    }
  }

  rep(i,N){
    int sz=ts[i].count(ts[i].root);
    rep(j,sz-1)cout<<(char)(ts[i].find(j+1)->val+'a');
    cout<<endl;
  }
  return 0;
}
accuracy: 1
time_ms: 760
memory_kb: 148288
final_rank: 14

code_snippet: #include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll> P;

#define fi first
#define se second
#define repl(i,a,b) for(ll i=(ll)(a);i<(ll)(b);i++)
#define rep(i,n) repl(i,0,n)
#define all(x) (x).begin(),(x).end()
#define dbg(x) cout<<#x"="<<x<<endl
#define mmax(x,y) (x>y?x:y)
#define mmin(x,y) (x<y?x:y)
#define maxch(x,y) x=mmax(x,y)
#define minch(x,y) x=mmin(x,y)
#define uni(x) x.erase(unique(all(x)),x.end())
#define exist(x,y) (find(all(x),y)!=x.end())
#define bcnt __builtin_popcount

template<class T>
struct treap{
    struct node_t{
        T val; // 値
        node_t *lch, *rch;
        int pri; // 優先度
        int cnt; // 部分木のサイズ
        // T sum; // 部分木の値の和
        // T mn; // 部分木の最小値

        node_t(T v, int p):val(v), pri(p), cnt(1){
            lch = rch = NULL;
        }
    };

    const T INF = 19191919; // TODO:initialize
    mt19937 mt;
    node_t *root;
    treap():root(NULL){
        const int seed = 364364;
        mt = mt19937(seed);
    }

    int count(node_t *t){ return t ? t->cnt : 0; }
    // T sum(node_t *t){ return t ? t->sum : 0; }
    // T min(node_t *t){ return t ? t->mn : INF; }

    node_t *update(node_t *t){
        t->cnt = count(t->lch) + count(t->rch) + 1;
        // t->sum = sum(t->lch) + sum(t->rch) + t->val;
        // t->mn = std::min({min(t->lch), min(t->rch), t->val});
        return t;
    }

    node_t *merge(node_t *l, node_t *r){
        if(!l || !r) return l?l:r;

        if(l->pri > r->pri){ // 左の部分木の根のほうが優先度が高い
            l->rch = merge(l->rch, r);
            return update(l);
        }
        else{
            r->lch = merge(l, r->lch);
            return update(r);
        }
    }

    pair<node_t*, node_t*> split(node_t *t, int k){ // [0,k), [k,n)
        if(!t) return {NULL,NULL};
        if(k <= count(t->lch)){
            auto s = split(t->lch,k);
            t->lch = s.second;
            return {s.first, update(t)};
        }
        else{
            auto s = split(t->rch, k-count(t->lch)-1);
            t->rch = s.first;
            return {update(t), s.second};
        }
    }

    node_t *insert(node_t *t, int k, T val, int pri){
        auto s = split(t,k);
        t = merge(s.first, new node_t(val,pri));
        t = merge(t, s.second);
        return update(t);
    }

    node_t *erase(node_t *t, int k){
        auto s2 = split(t,k+1);
        auto s1 = split(s2.first, k);
        t = merge(s1.first, s2.second);
        return update(t);
    }

    node_t *find(node_t *t, int k){
        int c = count(t->lch);
        if(k < c) return find(t->lch,k);
        if(k == c) return t;
        return find(t->rch, k-c-1);
    }

    void insert(int k, T val){ root = insert(root, k, val, mt()); }
    void erase(int k){ root = erase(root, k); }
    node_t *find(int k){ return find(root,k); }

    // // circular shift (右端の値が左端に来て、それ以外が右に1つずつシフト)
    // void shift(int l, int r){
    //     if(r-l==1) return;
    //     assert(l<r);
    //     auto sr = split(root, r);
    //     auto sl = split(sr.first, l);
    //     auto lr = split(sl.second, r-l-1);
    //     root = merge(merge(sl.first, merge(lr.second, lr.first)), sr.second);
    // }

    // // [l,r)
    // T min(int l, int r){
    //     assert(l<r);
    //     auto sr = split(root, r);
    //     auto sl = split(sr.first, l);
    //     auto lr = sl.second;
    //     T ret = min(lr);
    //     // 元に戻す
    //     root = merge(merge(sl.first, lr), sr.second);
    //     return ret;
    // }
};

int N,Q;
vector<treap<int> > ts;

int main(){
  scanf("%d %d ",&N,&Q);
  ts.resize(N);
  rep(i,N){
    ts[i].insert(0,-1);
    int j=1;
    while(1){
      char c;
      scanf("%c",&c);
      if(c=='\n')break;
      ts[i].insert(j++,c-'a');
    }
  }

  while(Q--){
    int tp;
    scanf(" %d",&tp);
    if(tp==1){
      int a,b,c,d;
      scanf(" %d %d %d %d",&a,&b,&c,&d);
      a--;c--;

      auto pa=ts[a].split(ts[a].root,b);
      auto pc=ts[c].split(ts[c].root,d);

      ts[a].root=ts[c].merge(pa.fi,pc.se);
      ts[c].root=ts[c].merge(pc.fi,pa.se);
    }else{
      int a,b;
      char c;
      scanf(" %d %d %c",&a,&b,&c);
      a--;

      ts[a].erase(b);
      ts[a].insert(b,c-'a');
    }
  }

  rep(i,N){
    int sz=ts[i].count(ts[i].root);
    rep(j,sz-1)cout<<(char)(ts[i].find(j+1)->val+'a');
    cout<<endl;
  }
  return 0;
}
accuracy: 1
time_ms: 760
memory_kb: 148328
final_rank: 15

code_snippet: #include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll> P;

#define fi first
#define se second
#define repl(i,a,b) for(ll i=(ll)(a);i<(ll)(b);i++)
#define rep(i,n) repl(i,0,n)
#define all(x) (x).begin(),(x).end()
#define dbg(x) cout<<#x"="<<x<<endl
#define mmax(x,y) (x>y?x:y)
#define mmin(x,y) (x<y?x:y)
#define maxch(x,y) x=mmax(x,y)
#define minch(x,y) x=mmin(x,y)
#define uni(x) x.erase(unique(all(x)),x.end())
#define exist(x,y) (find(all(x),y)!=x.end())
#define bcnt __builtin_popcount

template<class T>
struct treap{
    struct node_t{
        T val; // 値
        node_t *lch, *rch;
        int pri; // 優先度
        int cnt; // 部分木のサイズ
        // T sum; // 部分木の値の和
        // T mn; // 部分木の最小値

        node_t(T v, int p):val(v), pri(p), cnt(1){
            lch = rch = NULL;
        }
    };

    const T INF = 19191919; // TODO:initialize
    mt19937 mt;
    node_t *root;
    treap():root(NULL){
        const int seed = 364364;
        mt = mt19937(seed);
    }

    int count(node_t *t){ return t ? t->cnt : 0; }
    // T sum(node_t *t){ return t ? t->sum : 0; }
    // T min(node_t *t){ return t ? t->mn : INF; }

    node_t *update(node_t *t){
        t->cnt = count(t->lch) + count(t->rch) + 1;
        // t->sum = sum(t->lch) + sum(t->rch) + t->val;
        // t->mn = std::min({min(t->lch), min(t->rch), t->val});
        return t;
    }

    node_t *merge(node_t *l, node_t *r){
        if(!l || !r) return l?l:r;

        if(l->pri > r->pri){ // 左の部分木の根のほうが優先度が高い
            l->rch = merge(l->rch, r);
            return update(l);
        }
        else{
            r->lch = merge(l, r->lch);
            return update(r);
        }
    }

    pair<node_t*, node_t*> split(node_t *t, int k){ // [0,k), [k,n)
        if(!t) return {NULL,NULL};
        if(k <= count(t->lch)){
            auto s = split(t->lch,k);
            t->lch = s.second;
            return {s.first, update(t)};
        }
        else{
            auto s = split(t->rch, k-count(t->lch)-1);
            t->rch = s.first;
            return {update(t), s.second};
        }
    }

    node_t *insert(node_t *t, int k, T val, int pri){
        auto s = split(t,k);
        t = merge(s.first, new node_t(val,pri));
        t = merge(t, s.second);
        return update(t);
    }

    node_t *erase(node_t *t, int k){
        auto s2 = split(t,k+1);
        auto s1 = split(s2.first, k);
        t = merge(s1.first, s2.second);
        return update(t);
    }

    node_t *find(node_t *t, int k){
        int c = count(t->lch);
        if(k < c) return find(t->lch,k);
        if(k == c) return t;
        return find(t->rch, k-c-1);
    }

    void insert(int k, T val){ root = insert(root, k, val, mt()); }
    void erase(int k){ root = erase(root, k); }
    node_t *find(int k){ return find(root,k); }

    // // circular shift (右端の値が左端に来て、それ以外が右に1つずつシフト)
    // void shift(int l, int r){
    //     if(r-l==1) return;
    //     assert(l<r);
    //     auto sr = split(root, r);
    //     auto sl = split(sr.first, l);
    //     auto lr = split(sl.second, r-l-1);
    //     root = merge(merge(sl.first, merge(lr.second, lr.first)), sr.second);
    // }

    // // [l,r)
    // T min(int l, int r){
    //     assert(l<r);
    //     auto sr = split(root, r);
    //     auto sl = split(sr.first, l);
    //     auto lr = sl.second;
    //     T ret = min(lr);
    //     // 元に戻す
    //     root = merge(merge(sl.first, lr), sr.second);
    //     return ret;
    // }
};

int N,Q;
vector<treap<int> > ts;

int main(){
  scanf("%d %d ",&N,&Q);
  ts.resize(N);
  rep(i,N){
    ts[i].insert(0,-1);
    int j=1;
    while(1){
      char c;
      scanf("%c",&c);
      if(c=='\n')break;
      ts[i].insert(j++,c-'a');
    }
  }

  while(Q--){
    int tp;
    scanf(" %d",&tp);
    if(tp==1){
      int a,b,c,d;
      scanf(" %d %d %d %d",&a,&b,&c,&d);
      a--;c--;

      auto pa=ts[a].split(ts[a].root,b);
      auto pc=ts[c].split(ts[c].root,d);

      ts[a].root=ts[a].merge(pa.fi,pc.se);
      ts[c].root=ts[c].merge(pc.fi,pa.se);
    }else{
      int a,b;
      char c;
      scanf(" %d %d %c",&a,&b,&c);
      a--;

      ts[a].erase(b);
      ts[a].insert(b,c-'a');
    }
  }

  rep(i,N){
    int sz=ts[i].count(ts[i].root);
    rep(j,sz-1)cout<<(char)(ts[i].find(j+1)->val+'a');
    cout<<endl;
  }
  return 0;
}
accuracy: 1
time_ms: 740
memory_kb: 148312
final_rank: 13

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i,n) for(int (i)=0;(i)<(int)(n);++(i))
#define all(x) (x).begin(),(x).end()
#define pb push_back
#define fi first
#define se second
#define dbg(x) cout<<#x" = "<<((x))<<endl
template<class T,class U> ostream& operator<<(ostream& o, const pair<T,U> &p){o<<"("<<p.fi<<","<<p.se<<")";return o;}
template<class T> ostream& operator<<(ostream& o, const vector<T> &v){o<<"[";for(T t:v){o<<t<<",";}o<<"]";return o;}

template<class T>
struct treap{
    struct node_t{
        T val; // 値
        node_t *lch, *rch;
        int pri; // 優先度
        int cnt; // 部分木のサイズ

        node_t(T v, int p):val(v), pri(p), cnt(1){
            lch = rch = NULL;
        }
    };

    const T INF = 19191919; // TODO:initialize
    mt19937 mt;
    node_t *root;
    treap():root(NULL){
        const int seed = 364364;
        mt = mt19937(seed);
    }

    int count(node_t *t){ return t ? t->cnt : 0; }

    node_t *update(node_t *t){
        t->cnt = count(t->lch) + count(t->rch) + 1;
        return t;
    }

    node_t *merge(node_t *l, node_t *r){
        if(!l || !r) return l?l:r;

        if(l->pri > r->pri){ // 左の部分木の根のほうが優先度が高い
            l->rch = merge(l->rch, r);
            return update(l);
        }
        else{
            r->lch = merge(l, r->lch);
            return update(r);
        }
    }

    pair<node_t*, node_t*> split(node_t *t, int k){ // [0,k), [k,n)
        if(!t) return {NULL,NULL};
        if(k <= count(t->lch)){
            auto s = split(t->lch,k);
            t->lch = s.second;
            return {s.first, update(t)};
        }
        else{
            auto s = split(t->rch, k-count(t->lch)-1);
            t->rch = s.first;
            return {update(t), s.second};
        }
    }

    node_t *insert(node_t *t, int k, T val, int pri){
        auto s = split(t,k);
        t = merge(s.first, new node_t(val,pri));
        t = merge(t, s.second);
        return update(t);
    }

    node_t *erase(node_t *t, int k){
        auto s2 = split(t,k+1);
        auto s1 = split(s2.first, k);
        t = merge(s1.first, s2.second);
        return update(t);
    }

    node_t *find(node_t *t, int k){
        int c = count(t->lch);
        if(k < c) return find(t->lch,k);
        if(k == c) return t;
        return find(t->rch, k-c-1);
    }

    void insert(int k, T val){ root = insert(root, k, val, mt()); }
    void erase(int k){ root = erase(root, k); }
    node_t *find(int k){ return find(root,k); }
};

vector<treap<int>> t;

inline void read(int i){
    t[i].insert(0,'#');
    int j=1;
    while(1){
        char c;
        scanf("%c", &c);
        if(c=='\n') break;
        t[i].insert(j++, c-'a');
    }
}

void CHANGE(int a, int b, int c, int d){
    auto pa = t[a].split(t[a].root, b);
    auto pc = t[c].split(t[c].root, d);

    t[a].root = t[a].merge(pa.fi, pc.se);
    t[c].root = t[c].merge(pc.fi, pa.se);
}

void UPDATE(int a, int b, int c){
    t[a].erase(b);
    t[a].insert(b,c);
}

int main(){
    int n,q;
    scanf("%d %d ", &n, &q);

    t.resize(n);
    rep(i,n) read(i);

    // query
    rep(i,q){
        int tp;
        scanf(" %d", &tp);
        if(tp==1){
            int a,b,c,d;
            scanf(" %d %d %d %d", &a, &b, &c, &d);
            --a; --c;
            CHANGE(a,b,c,d);
        }
        else{
            int a,b;
            char c;
            scanf(" %d %d %c", &a, &b, &c);
            --a;
            UPDATE(a,b,c-'a');
        }
    }

    // 復元
    rep(i,n){
        int sz = t[i].count(t[i].root);
        rep(j,sz-1) printf("%c", t[i].find(j+1)->val+'a');
        printf("\n");
    }
    return 0;
}
accuracy: 1
time_ms: 700
memory_kb: 148308
final_rank: 11

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i,n) for(int (i)=0;(i)<(int)(n);++(i))
#define all(x) (x).begin(),(x).end()
#define pb push_back
#define fi first
#define se second
#define dbg(x) cout<<#x" = "<<((x))<<endl
template<class T,class U> ostream& operator<<(ostream& o, const pair<T,U> &p){o<<"("<<p.fi<<","<<p.se<<")";return o;}
template<class T> ostream& operator<<(ostream& o, const vector<T> &v){o<<"[";for(T t:v){o<<t<<",";}o<<"]";return o;}

template<class T>
struct treap{
    struct node_t{
        T val; // 値
        node_t *lch, *rch;
        int pri; // 優先度
        int cnt; // 部分木のサイズ
        // T sum; // 部分木の値の和
        // T mn; // 部分木の最小値

        node_t(T v, int p):val(v), pri(p), cnt(1){
            lch = rch = NULL;
        }
    };

    const T INF = 19191919; // TODO:initialize
    mt19937 mt;
    node_t *root;
    treap():root(NULL){
        const int seed = 364364;
        mt = mt19937(seed);
    }

    int count(node_t *t){ return t ? t->cnt : 0; }
    // T sum(node_t *t){ return t ? t->sum : 0; }
    // T min(node_t *t){ return t ? t->mn : INF; }

    node_t *update(node_t *t){
        t->cnt = count(t->lch) + count(t->rch) + 1;
        // t->sum = sum(t->lch) + sum(t->rch) + t->val;
        // t->mn = std::min({min(t->lch), min(t->rch), t->val});
        return t;
    }

    node_t *merge(node_t *l, node_t *r){
        if(!l || !r) return l?l:r;

        if(l->pri > r->pri){ // 左の部分木の根のほうが優先度が高い
            l->rch = merge(l->rch, r);
            return update(l);
        }
        else{
            r->lch = merge(l, r->lch);
            return update(r);
        }
    }

    pair<node_t*, node_t*> split(node_t *t, int k){ // [0,k), [k,n)
        if(!t) return {NULL,NULL};
        if(k <= count(t->lch)){
            auto s = split(t->lch,k);
            t->lch = s.second;
            return {s.first, update(t)};
        }
        else{
            auto s = split(t->rch, k-count(t->lch)-1);
            t->rch = s.first;
            return {update(t), s.second};
        }
    }

    node_t *insert(node_t *t, int k, T val, int pri){
        auto s = split(t,k);
        t = merge(s.first, new node_t(val,pri));
        t = merge(t, s.second);
        return update(t);
    }

    node_t *erase(node_t *t, int k){
        auto s2 = split(t,k+1);
        auto s1 = split(s2.first, k);
        t = merge(s1.first, s2.second);
        return update(t);
    }

    node_t *find(node_t *t, int k){
        int c = count(t->lch);
        if(k < c) return find(t->lch,k);
        if(k == c) return t;
        return find(t->rch, k-c-1);
    }

    void insert(int k, T val){ root = insert(root, k, val, mt()); }
    void erase(int k){ root = erase(root, k); }
    node_t *find(int k){ return find(root,k); }

    // // circular shift (右端の値が左端に来て、それ以外が右に1つずつシフト)
    // void shift(int l, int r){
    //     if(r-l==1) return;
    //     assert(l<r);
    //     auto sr = split(root, r);
    //     auto sl = split(sr.first, l);
    //     auto lr = split(sl.second, r-l-1);
    //     root = merge(merge(sl.first, merge(lr.second, lr.first)), sr.second);
    // }

    // // [l,r)
    // T min(int l, int r){
    //     assert(l<r);
    //     auto sr = split(root, r);
    //     auto sl = split(sr.first, l);
    //     auto lr = sl.second;
    //     T ret = min(lr);
    //     // 元に戻す
    //     root = merge(merge(sl.first, lr), sr.second);
    //     return ret;
    // }
};

vector<treap<int>> t;

inline void read(int i){
    t[i].insert(0,'#');
    int j=1;
    while(1){
        char c;
        scanf("%c", &c);
        if(c=='\n') break;
        t[i].insert(j++, c-'a');
    }
}

void CHANGE(int a, int b, int c, int d){
    auto pa = t[a].split(t[a].root, b);
    auto pc = t[c].split(t[c].root, d);

    t[a].root = t[a].merge(pa.fi, pc.se);
    t[c].root = t[c].merge(pc.fi, pa.se);
}

void UPDATE(int a, int b, int c){
    t[a].erase(b);
    t[a].insert(b,c);
}

int main(){
    int n,q;
    scanf("%d %d ", &n, &q);

    t.resize(n);
    rep(i,n) read(i);

    // query
    rep(i,q){
        int tp;
        scanf(" %d", &tp);
        if(tp==1){
            int a,b,c,d;
            scanf(" %d %d %d %d", &a, &b, &c, &d);
            --a; --c;
            // --b; --d;
            CHANGE(a,b,c,d);
        }
        else{
            int a,b;
            char c;
            scanf(" %d %d %c", &a, &b, &c);
            --a;
            // --b;
            UPDATE(a,b,c-'a');
        }
    }

    // 復元
    rep(i,n){
        int sz = t[i].count(t[i].root);
        // dbg(sz);
        rep(j,sz-1) printf("%c", t[i].find(j+1)->val+'a');
        printf("\n");
    }

    return 0;
}
accuracy: 1
time_ms: 720
memory_kb: 148344
final_rank: 12

code_snippet: #include <bits/stdc++.h>
#define REP(i, a, n) for (ll i = ((ll) a); i < ((ll) n); i++)
using namespace std;
typedef long long ll;

struct seg {
  ll idx, l, r, next;
};

int main(void) {
  ll N, Q;
  cin >> N >> Q;
  vector<string> S(N);
  REP(i, 0, N) cin >> S[i];

  vector<seg> segments(5 * 100000);
  ll s = 0;

  vector<ll> head(N);
  REP(i, 0, N) {
    segments[s].idx = i;
    segments[s].l = 0;
    segments[s].r = S[i].length();
    segments[s].next = -1;
    head[i] = s++;
  }

  REP(i, 0, Q) {
    ll T;
    cin >> T;

    if (T == 1) {
      ll A, B, C, D;
      cin >> A >> B >> C >> D, A--, B--, C--, D--;

      ll a = head[A], b = B;
      while (b >= segments[a].r - segments[a].l) {
        b -= segments[a].r - segments[a].l;
        a = segments[a].next;
      }

      ll c = head[C], d = D;
      while (d >= segments[c].r - segments[c].l) {
        d -= segments[c].r - segments[c].l;
        c = segments[c].next;
      }

      ll segA = s++, segC = s++;
      segments[segA].idx = segments[a].idx;
      segments[segA].r = segments[a].r;
      segments[segA].l = segments[a].l + b;
      segments[segA].next = segments[a].next;
      segments[segC].idx = segments[c].idx;
      segments[segC].r = segments[c].r;
      segments[segC].l = segments[c].l + d;
      segments[segC].next = segments[c].next;

      segments[a].r = segments[segA].l;
      segments[a].next = segC;
      segments[c].r = segments[segC].l;
      segments[c].next = segA;
    }

    if (T == 2) {
      ll A, B;
      char C;
      cin >> A >> B >> C, A--, B--;

      ll a = head[A], b = B;
      while (b >= segments[a].r - segments[a].l) {
        b -= segments[a].r - segments[a].l;
        a = segments[a].next;
      }

      S[segments[a].idx][segments[a].l + b] = C;
    }

    if ((i + 1) % 310 == 0 || i + 1 == Q) {
      vector<string> T(N);
      REP(j, 0, N) {
        T[j] = "";
        ll a = head[j];
        while (a != -1) {
          T[j] += S[segments[a].idx].substr(segments[a].l, segments[a].r - segments[a].l);
          a = segments[a].next;
        }
      }
      S = T;

      s = 0;
      REP(j, 0, N) {
        segments[s].idx = j;
        segments[s].l = 0;
        segments[s].r = S[j].length();
        segments[s].next = -1;
        head[j] = s++;
      }
    }
  }

  REP(i, 0, N) cout << S[i] << endl;
}
accuracy: 1
time_ms: 750
memory_kb: 30320
final_rank: 2

code_snippet: #include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef complex<double> P;
#define REP(i,n) for(int i=0;i<n;++i)
#define REPR(i,n) for(int i=1;i<n;++i)

#define DEBUG(x) cout<<#x<<": "<<x<<endl
#define DEBUG_VEC(v) REP(i,v.size())cout<<#v<<"["<<i<<"]: "<<v[i]<<endl
#define ALL(a) (a).begin(),(a).end()

// ??????????????¨????????????

// ????????°???????????°?????????????????§?????????????§???? 2????????????????????¢?´¢??¨??¨???
// http://www.slideshare.net/iwiwi/2-12188757
// ????????????

struct node_t{
  char val;
  node_t *ch[2];
  ll pri;
  int cnt;
  // string sum;
  node_t(char v,ll p):val(v),pri(p),cnt(1){
    // sum = "";
    // sum += v;
    ch[0]=ch[1]=NULL;
  }
};
int count(node_t *t){
  return t==NULL ? 0 : t->cnt;
}
// string sum(node_t *t){
//   return t==NULL ? "" : t->sum;
// }
node_t* update(node_t *t){
  t->cnt = count(t->ch[0]) + 1 + count(t->ch[1]);
  // t->sum = sum(t->ch[0]) + t->val + sum(t->ch[1]);
  return t;
}
node_t* merge(node_t *l, node_t *r){
  if(!l || !r) return !l?r:l;
  if(l->pri > r->pri){
    l->ch[1] = merge(l->ch[1],r);
    return update(l);
  }else{
    r->ch[0] = merge(l,r->ch[0]);
    return update(r);
  }
}
pair<node_t*,node_t*> split(node_t *t, int k){
  if(!t) return make_pair((node_t*)NULL,(node_t*)NULL);
  if(k <= count(t->ch[0])){
    pair<node_t*,node_t*> s = split(t->ch[0],k);
    t->ch[0] = s.second;
    return make_pair(s.first,update(t));
  }else{
    pair<node_t*,node_t*> s = split(t->ch[1],k-count(t->ch[0])-1);
    t->ch[1] = s.first;
    return make_pair(update(t),s.second);
  }
}
node_t* insert(node_t *t,int k,char val,ll pri){
  pair<node_t*,node_t*> lr = split(t,k);
  node_t* v = new node_t(val,pri);
  node_t* p = merge(lr.first,v);
  return merge(p,lr.second);
}
node_t* erase(node_t *t,int k){
  pair<node_t*,node_t*> mr = split(t,k);
  pair<node_t*,node_t*> lm = split(mr.first,k-1);
  return merge(lm.first,mr.second);
}
void renew(node_t *t,int k,char val){
  node_t *target = t;
  vector<node_t*> l;
  int cnt = count(target);
  int left = 0;
  while(true){
    l.push_back(target);
    int lcnt = count(target->ch[0]);
    if(left+lcnt==k)break;
    if(left+lcnt>k)target = target->ch[0];
    if(left+lcnt<k){
      target = target->ch[1];
      left += lcnt+1;
    }
  }
  target->val = val;
  int sz = l.size();
  REP(i_,sz){
    int i = sz-1-i_;
    update(l[i]);
  }
}
void dfs(node_t *t,char *res){
  if(!t)return;
  int lcnt = count(t->ch[0]);
  res[lcnt] = t->val;
  dfs(t->ch[0],res);
  dfs(t->ch[1],res+lcnt+1);
}
void output(node_t *t){
  int len = count(t);
  char ret[len];
  dfs(t,ret);
  REP(i,len)cout<<ret[i];
  cout<<endl;
}

node_t* str[100010];

ll rd(){
  // xorshift
  static ll x = 123456789, y = 362436069, z = 521288629, w = 88675123;
  ll t;
  t = x ^ (x<<11);
  x=y;y=z;z=w;
  return w=(w^(w>>19)^(t^(t>>8)));
}

int main(){
  int N,Q;
  cin >> N >> Q;
  // string S[N];
  // REP(i,N) cin >> S[i];
  REP(i,N){
    string s;
    cin>>s;
    int len = s.size();
    str[i] = new node_t(s[0],rd());
    REPR(j,len){
      str[i] = insert(str[i],count(str[i]),s[j],rd());
    }
  }
  REP(_,Q){
    int q_type;
    cin>>q_type;
    if(q_type == 1){
      int a,b,c,d;
      cin>>a>>b>>c>>d;
      --a;--b;--c;--d;
      pair<node_t*,node_t*> sa = split(str[a],b);
      pair<node_t*,node_t*> sc = split(str[c],d);
      str[a] = merge(sa.first,sc.second);
      str[c] = merge(sc.first,sa.second);
    }else{
      int a,b;
      char c;
      cin>>a>>b>>c;
      --a;--b;
      renew(str[a],b,c);
      // str[a] = erase(str[a],b+1);
      // str[a] = insert(str[a],b,c,rd());
    }
  }
  REP(i,N){
    // cout << output(str[i]) << endl;
    output(str[i]);
  }
  return 0;
}
accuracy: 1
time_ms: 860
memory_kb: 97616
final_rank: 10

code_snippet: #include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<string>
#include<stack>
#include<cstdio>
#include<cmath>
#include<time.h>
#include<cstdlib>
using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<int,int> P;
typedef pair<int,P> P1;

#define fr first
#define sc second
#define mp make_pair
#define pb push_back
#define rep(i,x) for(int i=0;i<x;i++)
#define rep1(i,x) for(int i=1;i<=x;i++)
#define rrep(i,x) for(int i=x-1;i>=0;i--)
#define rrep1(i,x) for(int i=x;i>0;i--)
#define sor(v) sort(v.begin(),v.end())
#define rev(s) reverse(s.begin(),s.end())
#define lb(vec,a) lower_bound(vec.begin(),vec.end(),a)
#define ub(vec,a) upper_bound(vec.begin(),vec.end(),a)
#define uniq(vec) vec.erase(unique(vec.begin(),vec.end()),vec.end())
#define mp1(a,b,c) P1(a,P(b,c))

const int INF=1000000000;
const int dir_4[4][2]={{1,0},{0,1},{-1,0},{0,-1}};
const int dir_8[8][2]={{1,0},{1,1},{0,1},{-1,1},{-1,0},{-1,-1},{0,-1},{1,-1}};

struct node{
	char c;
	node *next,*down;
	int siz;
};

const double p = 0.30;
const int max_height = 10;
node null;

struct slis{
	int n;
	node head;
	void show(){
		node *h[max_height];
		h[max_height-1] = &head;
		rrep(i,max_height-1)h[i] = (*h[i+1]).down;
		rrep(i,max_height){
			printf("%d:",i);
			while(h[i] != &null){
				printf("%c,%d ",h[i]->c,h[i]->siz);
				h[i] = h[i]->next;
			}
			cout << endl;
		}
	}
	void show_(){
		node* id = &head;
		while(id->down != &null)id = id->down;
		while(id->next != &null){
			id = id->next;
			printf("%c",id->c);
		}
		puts("");
	}
};

node* init(){//0???????????????
	node* h = new node;
	node* head[max_height];
	head[max_height-1] = h;
	rrep1(i,max_height-1){
		head[i]->c = '$';
		head[i]->down = new node;
		head[i-1] = head[i]->down;
	}
	head[0]->c = '$';
	head[0]->down = &null;
	return h;
}
	

slis* mkslis(int n,char *c,slis *ret){
	
	//???????´??????????????±??????????
	vector<int> height;
	rep(i,n){
		int h = 1;
		while(h < max_height && rand()%100 < p*100.0)h ++;
		height.pb(h);
	}
	
	//0???????????????
	node* head[max_height];
	head[max_height-1] = init();
	rrep1(i,max_height-1)head[i-1] = head[i]->down;
	/*node* h = new node;
	node* head[max_height];
	head[max_height-1] = h;
	rrep1(i,max_height-1){
		head[i]->c = '$';
		head[i]->down = new node;
		head[i-1] = head[i]->down;
	}
	head[0]->c = '$';
	head[0]->down = &null;*/
	
	//??¬????????????
	vector<node*> down;
	rep(i,n)down.pb(&null);
	rep(i,max_height){
		node *id = head[i];
		int loc = 0;
		rep(j,n){
			if(i < height[j]){
				(*id).next = new node;
				(*id).siz = j+1-loc;
				loc = j+1;
				id = (*id).next;
				(*id).c = *(c+j);
				(*id).down = down[j];
				down[j] = id;
			}
		}
		(*id).next = &null;
		(*id).siz = n-loc;
	}
	
	(*ret).n = n;
	(*ret).head = *head[max_height-1];
	return ret;
}

pair<slis*,slis*> split(slis *a,slis *b,int k){
	//b???0???????????????
	node* head[max_height];
	head[max_height-1] = init();
	rrep1(i,max_height-1)head[i-1] = head[i]->down;
	
	//split
	node* id = &a->head;
	int loc = 0;
	int h = max_height-1;
	while(1){
		while(loc + id->siz <= k){
			loc += id->siz;
			id = id->next;
		}
		head[h]->next = id->next;
		head[h]->siz = loc + id->siz - k;
		id->next = &null;
		id->siz = k - loc;
		if(id->down == &null)break;
		id = id->down;
		h --;
	}
	
	//??????
	b->n = a->n - k;
	a->n = k;
	b->head = *head[max_height-1];
	return pair<slis*,slis*>(a,b);
}

slis* merge(slis* a,slis* b){
	node* id0 = &a->head;
	node* id1 = &b->head;
	while(id0 != &null){
		while(id0->next != &null)id0 = id0->next;
		id0->next = id1->next;
		id0->siz += id1->siz;
		id0 = id0->down;
		id1 = id1->down;
	}
	a->n += b->n;
	return a;
}

void updata(slis* lis,int k,char c){
	node* id = &lis->head;
	int loc = 0;
	while(id != &null){
		while(id->next != &null && loc + id->siz <= k){
			loc += id->siz;
			id = id->next;
		}
		if(loc == k)id->c = c;
		id = id->down;
	}
}

int main(){
	static int n,q;
	static char c[2000010];
	static slis* s[100010];
	scanf("%d%d",&n,&q);
	rep(i,n){
		scanf("%s",&c);
		int siz = 0;
		while(c[siz] != '\0')siz ++;
		s[i] = mkslis(siz,c,new slis);
		rep(j,siz)c[j] = '\0';
	}
	rep(i,q){
		int t;
		scanf("%d",&t);
		if(t == 1){
			int a,b,c,d;
			scanf("%d%d%d%d",&a,&b,&c,&d);
			pair<slis*,slis*> p = split(s[a-1],new slis,b-1);
			pair<slis*,slis*> q = split(s[c-1],new slis,d-1);
			s[a-1] = merge(p.fr,q.sc);
			s[c-1] = merge(q.fr,p.sc);
		}
		else {
			int a,b;
			char c_;
			scanf("%d%d %c",&a,&b,&c_);
			updata(s[a-1],b,c_);
		}
	}
	
	rep(i,n){
		s[i]->show_();
	}
	
	/*int n;
	char c[30];
	scanf("%d %s",&n,&c);
	slis *test = new slis;
	test = mkslis(n,c,test);
	test->show();
	int k;
	scanf("%d",&k);
	pair<slis*,slis*> p = split(test,new slis,k);
	p.fr->show();
	p.sc->show();
	test = merge(p.fr,p.sc);
	test->show();*/
}
accuracy: 1
time_ms: 530
memory_kb: 239200
final_rank: 17

code_snippet: #include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<string>
#include<stack>
#include<cstdio>
#include<cmath>
#include<time.h>
#include<cstdlib>
using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<int,int> P;
typedef pair<int,P> P1;

#define fr first
#define sc second
#define mp make_pair
#define pb push_back
#define rep(i,x) for(int i=0;i<x;i++)
#define rep1(i,x) for(int i=1;i<=x;i++)
#define rrep(i,x) for(int i=x-1;i>=0;i--)
#define rrep1(i,x) for(int i=x;i>0;i--)
#define sor(v) sort(v.begin(),v.end())
#define rev(s) reverse(s.begin(),s.end())
#define lb(vec,a) lower_bound(vec.begin(),vec.end(),a)
#define ub(vec,a) upper_bound(vec.begin(),vec.end(),a)
#define uniq(vec) vec.erase(unique(vec.begin(),vec.end()),vec.end())
#define mp1(a,b,c) P1(a,P(b,c))

const int INF=1000000000;
const int dir_4[4][2]={{1,0},{0,1},{-1,0},{0,-1}};
const int dir_8[8][2]={{1,0},{1,1},{0,1},{-1,1},{-1,0},{-1,-1},{0,-1},{1,-1}};

struct node{
	char c;
	node *next,*down;
	int siz;
};

const double p = 0.25;
const int max_height = 8;
node null;

struct slis{
	int n;
	node head;
	void show(){
		node *h[max_height];
		h[max_height-1] = &head;
		rrep(i,max_height-1)h[i] = (*h[i+1]).down;
		rrep(i,max_height){
			printf("%d:",i);
			while(h[i] != &null){
				printf("%c,%d ",h[i]->c,h[i]->siz);
				h[i] = h[i]->next;
			}
			cout << endl;
		}
	}
	void show_(){
		node* id = &head;
		while(id->down != &null)id = id->down;
		while(id->next != &null){
			id = id->next;
			printf("%c",id->c);
		}
		puts("");
	}
};

node* init(){//0???????????????
	node* h = new node;
	node* head[max_height];
	head[max_height-1] = h;
	rrep1(i,max_height-1){
		head[i]->c = '$';
		head[i]->down = new node;
		head[i-1] = head[i]->down;
	}
	head[0]->c = '$';
	head[0]->down = &null;
	return h;
}
	

slis* mkslis(int n,char *c,slis *ret){
	
	//???????´??????????????±??????????
	vector<int> height;
	rep(i,n){
		int h = 1;
		while(h < max_height && rand()%100 < p*100.0)h ++;
		height.pb(h);
	}
	
	//0???????????????
	node* head[max_height];
	head[max_height-1] = init();
	rrep1(i,max_height-1)head[i-1] = head[i]->down;
	/*node* h = new node;
	node* head[max_height];
	head[max_height-1] = h;
	rrep1(i,max_height-1){
		head[i]->c = '$';
		head[i]->down = new node;
		head[i-1] = head[i]->down;
	}
	head[0]->c = '$';
	head[0]->down = &null;*/
	
	//??¬????????????
	vector<node*> down;
	rep(i,n)down.pb(&null);
	rep(i,max_height){
		node *id = head[i];
		int loc = 0;
		rep(j,n){
			if(i < height[j]){
				(*id).next = new node;
				(*id).siz = j+1-loc;
				loc = j+1;
				id = (*id).next;
				(*id).c = *(c+j);
				(*id).down = down[j];
				down[j] = id;
			}
		}
		(*id).next = &null;
		(*id).siz = n-loc;
	}
	
	(*ret).n = n;
	(*ret).head = *head[max_height-1];
	return ret;
}

pair<slis*,slis*> split(slis *a,slis *b,int k){
	//b???0???????????????
	node* head[max_height];
	head[max_height-1] = init();
	rrep1(i,max_height-1)head[i-1] = head[i]->down;
	
	//split
	node* id = &a->head;
	int loc = 0;
	int h = max_height-1;
	while(1){
		while(loc + id->siz <= k){
			loc += id->siz;
			id = id->next;
		}
		head[h]->next = id->next;
		head[h]->siz = loc + id->siz - k;
		id->next = &null;
		id->siz = k - loc;
		if(id->down == &null)break;
		id = id->down;
		h --;
	}
	
	//??????
	b->n = a->n - k;
	a->n = k;
	b->head = *head[max_height-1];
	return pair<slis*,slis*>(a,b);
}

slis* merge(slis* a,slis* b){
	node* id0 = &a->head;
	node* id1 = &b->head;
	while(id0 != &null){
		while(id0->next != &null)id0 = id0->next;
		id0->next = id1->next;
		id0->siz += id1->siz;
		id0 = id0->down;
		id1 = id1->down;
	}
	a->n += b->n;
	return a;
}

void updata(slis* lis,int k,char c){
	node* id = &lis->head;
	int loc = 0;
	while(id != &null){
		while(id->next != &null && loc + id->siz <= k){
			loc += id->siz;
			id = id->next;
		}
		if(loc == k)id->c = c;
		id = id->down;
	}
}

int main(){
	static int n,q;
	static char c[2000010];
	static slis* s[100010];
	scanf("%d%d",&n,&q);
	rep(i,n){
		scanf("%s",&c);
		int siz = 0;
		while(c[siz] != '\0')siz ++;
		s[i] = mkslis(siz,c,new slis);
		rep(j,siz)c[j] = '\0';
	}
	rep(i,q){
		int t;
		scanf("%d",&t);
		if(t == 1){
			int a,b,c,d;
			scanf("%d%d%d%d",&a,&b,&c,&d);
			pair<slis*,slis*> p = split(s[a-1],new slis,b-1);
			pair<slis*,slis*> q = split(s[c-1],new slis,d-1);
			s[a-1] = merge(p.fr,q.sc);
			s[c-1] = merge(q.fr,p.sc);
		}
		else {
			int a,b;
			char c_;
			scanf("%d%d %c",&a,&b,&c_);
			updata(s[a-1],b,c_);
		}
	}
	
	rep(i,n){
		s[i]->show_();
	}
	
	/*int n;
	char c[30];
	scanf("%d %s",&n,&c);
	slis *test = new slis;
	test = mkslis(n,c,test);
	test->show();
	int k;
	scanf("%d",&k);
	pair<slis*,slis*> p = split(test,new slis,k);
	p.fr->show();
	p.sc->show();
	test = merge(p.fr,p.sc);
	test->show();*/
}
accuracy: 1
time_ms: 510
memory_kb: 211500
final_rank: 16

code_snippet: #include<bits/stdc++.h>
using namespace std;

struct treap{
    static const int INF=INT_MAX;

    struct node{
        int val,mini,cnt,pri;
        node *lch,*rch;

        node(int val,int pri):val(val),pri(pri),cnt(1),mini(val){
            lch=rch=NULL;
        }
    };

    node *root;
    treap():root(NULL){srand(time(NULL));}

    int count(node *t){return !t?0:t->cnt;}
    int mini(node *t){return !t?INF:t->mini;}

    node *update(node *t){
        if(!t)return t;
        t->cnt=count(t->lch)+count(t->rch)+1;
        t->mini=min(min(mini(t->lch),mini(t->rch)),t->val);
        return t;
    }

    node *merge(node *l,node *r){
        if(!l||!r)return l?l:r;
        if(l->pri>r->pri){
            l->rch=merge(l->rch,r);
            return update(l);
        }
        r->lch=merge(l,r->lch);
        return update(r);
    }

    pair<node *,node *>split(node *t,int k){
        if(!t)return make_pair((node *)NULL,(node *)NULL);
        if(count(t->lch)>=k){
            pair<node *,node *>s=split(t->lch,k);
            t->lch=s.second;
            return make_pair(s.first,update(t));
        }
        pair<node *,node *>s=split(t->rch,k-count(t->lch)-1);
        t->rch=s.first;
        return make_pair(update(t),s.second);
    }

    node *insert(node *t,int k,int val,int pri){
        pair<node *,node *>s=split(t,k);
        t=merge(s.first,new node(val,pri));
        t=merge(t,s.second);
        return update(t);
    }

    node *erase(node *t,int k){
        pair<node *,node *>s1,s2;
        s2=split(t,k+1);
        s1=split(s2.first,k);
        return update((t=merge(s1.first,s2.second)));
    }


    void insert(int k,int val){
        root=insert(root,k,val,rand());
    }

    void erase(int k){
        root=erase(root,k);
    }

    int rangeMinimumQuery(node *t,int l,int r){
        if(!t)return INF;
        int sz=count(t);
        if(sz<=l||r<=0)return INF;
        if(l<=0&&sz<=r)return mini(t);

        int cnt=count(t->lch);

        int vl=rangeMinimumQuery(t->lch,l,r);
        int vr=rangeMinimumQuery(t->rch,l-cnt-1,r-cnt-1);

        int res=min(vl,vr);
        if(l<=cnt&&cnt<r)res=min(res,t->val);
        return res;
    }

    int rangeMinimumQuery(int l,int r){
        return rangeMinimumQuery(root,l,r);
    }



    void updateNode(int k,int val){
        erase(k);
        insert(k,val);

    }

    void Debug(node *t){
        if(!t)return;
        Debug(t->lch);
        cout<<t->val<<" ";
        Debug(t->rch);
    }

    void Debug(){
        Debug(root);
        cout<<endl;
    }

    void query1(treap &t,int b,int d){
        pair<node *,node *>s1,s2;
        s1=split(root,b);
        s2=t.split(t.root,d);
        root=merge(s1.first,s2.second);
        t.root=merge(s2.first,s1.second);
    }

    void output(node *t){
        if(!t)return;
        output(t->lch);
        printf("%c",t->val+'a');
        output(t->rch);
    }
    void output(){
        output(root);
        puts("");
    }
};

vector<treap>v;
char latte[2000001];
int main(){
    int n,q;
    scanf("%d%d",&n,&q);

    v.resize(n);
    for(int i=0;i<n;i++){
        scanf("%s",latte);
        for(int j=0;latte[j];j++){
            v[i].insert(j,latte[j]-'a');
        }
    }

    while(q--){
        int type;
        scanf("%d",&type);
        if(type==1){
            int a,b,c,d;
            scanf("%d%d%d%d",&a,&b,&c,&d);
            a--;b--;c--;d--;
            v[a].query1(v[c],b,d);
        }
        else{
            int a,b;
            char c;
            scanf("%d%d %c",&a,&b,&c);
            a--;b--;
            v[a].updateNode(b,c-'a');
        }
    }

    for(int i=0;i<n;i++)v[i].output();
    return 0;
}
accuracy: 1
time_ms: 720
memory_kb: 100600
final_rank: 7

code_snippet: #include <cstdio>
#include <iostream>
#include <sstream>
#include <fstream>
#include <iomanip>
#include <algorithm>
#include <cmath>
#include <string>
#include <vector>
#include <list>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <bitset>
#include <numeric>
#include <limits>
#include <climits>
#include <cfloat>
#include <functional>
using namespace std;
 
int main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
 
    int n, q;
    cin >> n >> q;
    vector<list<string> > v(n+1);
    for(int i=1; i<=n; ++i){
        string s;
        cin >> s;
        for(unsigned j=0; j<s.size(); j+=1000)
            v[i].push_back(s.substr(j, 1000));
    }
 
    while(--q >= 0){
        int type;
        cin >> type;
 
        if(type == 1){
            int a, b, c, d;
            cin >> a >> b >> c >> d;
 
            auto it1 = v[a].begin();
            auto it2 = v[c].begin();
            while((int)it1->size() < b){
                b -= it1->size();
                ++ it1;
            }
            while((int)it2->size() < d){
                d -= it2->size();
                ++ it2;
            }
 
            string s = it2->substr(0, d-1) + it1->substr(b-1);
            string t = it1->substr(0, b-1) + it2->substr(d-1);
            *it1 = s;
            *it2 = t;
 
            list<string> x, y;
            x.splice(x.end(), v[a], v[a].begin(), it1);
            y.splice(y.end(), v[c], v[c].begin(), it2);
            x.splice(x.end(), v[c], v[c].begin(), v[c].end());
            y.splice(y.end(), v[a], v[a].begin(), v[a].end());
            v[a].swap(x);
            v[c].swap(y);
        }
        else{
            int a, b;
            char c;
            cin >> a >> b >> c;
 
            auto it = v[a].begin();
            while((int)it->size() < b){
                b -= it->size();
                ++ it;
            }
            (*it)[b-1] = c;
        }
    }
 
    for(int i=1; i<=n; ++i){
        for(const string& s : v[i])
            cout << s;
        cout << endl;
    }
 
    return 0;
}
accuracy: 1
time_ms: 1270
memory_kb: 6372
final_rank: 8

code_snippet: #include <cstdio>
#include <iostream>
#include <sstream>
#include <fstream>
#include <iomanip>
#include <algorithm>
#include <cmath>
#include <string>
#include <vector>
#include <list>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <bitset>
#include <numeric>
#include <limits>
#include <climits>
#include <cfloat>
#include <functional>
using namespace std;

class Data
{
public:
    string str;
    Data* next;
    Data(){
        next = NULL;
    }
};

int main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);

    int n, q;
    cin >> n >> q;
    vector<Data*> v(n+1, NULL);
    for(int i=1; i<=n; ++i){
        string s;
        cin >> s;
        Data **p = &v[i];
        for(unsigned j=0; j<s.size(); j+=1000){
            Data* d = new Data;
            d->str = s.substr(j, 1000);
            *p = d;
            p = &d->next;
        }
    }

    while(--q >= 0){
        int type;
        cin >> type;

        if(type == 1){
            int a, b, c, d;
            cin >> a >> b >> c >> d;

            Data* p1 = v[a];
            Data* p2 = v[c];
            while((int)p1->str.size() < b){
                b -= p1->str.size();
                p1 = p1->next;
            }
            while((int)p2->str.size() < d){
                d -= p2->str.size();
                p2 = p2->next;
            }

            string s = p1->str.substr(0, b-1) + p2->str.substr(d-1);
            string t = p2->str.substr(0, d-1) + p1->str.substr(b-1);
            p1->str = s;
            p2->str = t;

            swap(p1->next, p2->next);
        }
        else{
            int a, b;
            char c;
            cin >> a >> b >> c;

            Data* p = v[a];
            while((int)p->str.size() < b){
                b -= p->str.size();
                p = p->next;
            }
            p->str[b-1] = c;
        }
    }

    for(int i=1; i<=n; ++i){
        for(Data* p=v[i]; p!=NULL; p=p->next)
            cout << p->str;
        cout << endl;
    }

    return 0;
}
accuracy: 1
time_ms: 1210
memory_kb: 6388
final_rank: 6

code_snippet: #include<bits/stdc++.h>
using namespace std;
const int B=1000;
char latte[3000001];
string s[100000],_s[100000];
int n;
struct data{
    int id,l,r;
    data(int a,int b,int c):id(a),l(b),r(c){}
};

vector<data>v[100000];

void get(int a,int b,int &cur,int &sum){
    sum=cur=0;
    while(cur<(int)v[a].size()&&b-sum>=v[a][cur].r-v[a][cur].l){
        sum+=v[a][cur].r-v[a][cur].l;
        cur++;
    }
}


void div(int a,int b,vector<data>&X){
    int cur,sum;
    get(a,b,cur,sum);
    for(int i=(int)v[a].size()-1;i>cur;i--){
        //if(v[a].size()==0)continue;
        X.push_back(v[a].back());
        v[a].pop_back();
    }
    if(b==sum){
        //if(v[a].size()==0)return;
        X.push_back(v[a].back());
        v[a].pop_back();
    }
    else{
    //if(v[a].size()==0)return;
        data d=v[a].back();v[a].pop_back();
        v[a].push_back(data(d.id,d.l,d.l+b-sum));
        X.push_back(data(d.id,d.l+b-sum,d.r));
    }
}

void query1(){
    int a,b,c,d;
    scanf("%d%d%d%d",&a,&b,&c,&d);
    a--;b--;c--;d--;

    vector<data>X,Y;

    div(a,b,X);
    div(c,d,Y);

    for(int i=(int)Y.size()-1;i>=0;i--)v[a].push_back(Y[i]);
    for(int i=(int)X.size()-1;i>=0;i--)v[c].push_back(X[i]);
}

void query2(){
    int a,b;char c;
    scanf("%d%d %c",&a,&b,&c);
    a--;b--;

    int cur,sum;
    get(a,b,cur,sum);
    //if(cur>=v[a].size())return;
    int id=v[a][cur].id;
    int l=v[a][cur].l;
    int r=v[a][cur].r;
    //if(b-sum+l>=s[id].size())return;
    s[id][b-sum+l]=c;
}

void update(int query){
    for(int i=0;i<n;i++)v[i].clear();
    for(int i=0;i<n;i++)v[i].push_back(data(i,0,s[i].size()));

    for(int qry=0;qry<query;qry++){
        int type;scanf("%d",&type);
        if(type==1)query1();
        else query2();


    }



    for(int i=0;i<n;i++){
        _s[i]="";
        for(int j=0;j<v[i].size();j++){
            int id=v[i][j].id,l=v[i][j].l,r=v[i][j].r;
            if(r-l+l>s[id].size())continue;
            _s[i]+=s[id].substr(l,r-l);
        }
    }

    for(int i=0;i<n;i++)s[i]=_s[i];

}
int main(){
    int q;
    scanf("%d%d",&n,&q);
    for(int i=0;i<n;i++){
        scanf("%s",latte);
        s[i]=latte;
    }

    for(int i=0;i<(q+B-1)/B;i++){
        update(min(B,q-i*B));
    }
    for(int i=0;i<n;i++)printf("%s\n",s[i].c_str());

    return 0;
}
accuracy: 1
time_ms: 620
memory_kb: 18312
final_rank: 1

code_snippet: #include<bits/stdc++.h>
using namespace std;
const int B=1000;
char latte[3000001];
string s[100000],_s[100000];
int n;
struct data{
    int id,l,r;
    data(int a,int b,int c):id(a),l(b),r(c){}
};

vector<data>v[100000];

void get(int a,int b,int &cur,int &sum){
    sum=cur=0;
    while(cur<(int)v[a].size()&&b-sum>=v[a][cur].r-v[a][cur].l){
        sum+=v[a][cur].r-v[a][cur].l;
        cur++;
    }
}


void div(int a,int b,vector<data>&X){
    int cur,sum;
    get(a,b,cur,sum);
    for(int i=(int)v[a].size()-1;i>cur;i--){
        if(v[a].size()==0)continue;
        X.push_back(v[a].back());
        v[a].pop_back();
    }
    if(b==sum){
        if(v[a].size()==0)return;
        X.push_back(v[a].back());
        v[a].pop_back();
    }
    else{
        if(v[a].size()==0)return;
        data d=v[a].back();v[a].pop_back();
        v[a].push_back(data(d.id,d.l,d.l+b-sum));
        X.push_back(data(d.id,d.l+b-sum,d.r));
    }
}

void query1(){
    int a,b,c,d;
    scanf("%d%d%d%d",&a,&b,&c,&d);
    a--;b--;c--;d--;

    vector<data>X,Y;

    div(a,b,X);
    div(c,d,Y);

    for(int i=(int)Y.size()-1;i>=0;i--)v[a].push_back(Y[i]);
    for(int i=(int)X.size()-1;i>=0;i--)v[c].push_back(X[i]);
}

void query2(){
    int a,b;char c;
    scanf("%d%d %c",&a,&b,&c);
    a--;b--;

    int cur,sum;
    get(a,b,cur,sum);
    //if(cur>=v[a].size())return;
    int id=v[a][cur].id;
    int l=v[a][cur].l;
    int r=v[a][cur].r;
    //if(b-sum+l>=s[id].size())return;
    s[id][b-sum+l]=c;
}

void update(int query){
    for(int i=0;i<n;i++)v[i].push_back(data(i,0,s[i].size()));

    for(int qry=0;qry<query;qry++){
        int type;scanf("%d",&type);
        if(type==1)query1();
        else query2();



    }



    for(int i=0;i<n;i++){
        _s[i]="";
        for(int j=0;j<v[i].size();j++){
            int id=v[i][j].id,l=v[i][j].l,r=v[i][j].r;
            _s[i]+=s[id].substr(l,r-l);
        }
    }

    for(int i=0;i<n;i++)s[i]=_s[i];
}
int main(){
    int q;
    scanf("%d%d",&n,&q);
    for(int i=0;i<n;i++){
        scanf("%s",latte);
        s[i]=latte;
    }

    for(int i=0;i<(q+B-1)/B;i++)update(min(B,q-i*B));

    for(int i=0;i<n;i++)printf("%s\n",s[i].c_str());

    return 0;
}
accuracy: 0.14285714285714285
time_ms: 10
memory_kb: 10420
final_rank: 18

code_snippet: #include<bits/stdc++.h>
using namespace std;
int B=1000;
char latte[2000001];
string s[100000],_s[100000];
int n;
struct data{
    int id,l,r;
    data(int a,int b,int c):id(a),l(b),r(c){}
};

vector<data>v[100000];

void get(int a,int b,int &cur,int &sum){
    sum=cur=0;
    while(cur<(int)v[a].size()&&sum+v[a][cur].r-v[a][cur].l<=b){
        sum+=v[a][cur].r-v[a][cur].l;
        cur++;
    }
}


void div(int a,int b,vector<data>&X){
    int cur,sum;
    get(a,b,cur,sum);
    for(int i=(int)v[a].size()-1;i>cur;i--){
        if(v[a].size()==0)continue;
        X.push_back(v[a].back());
        v[a].pop_back();
    }
    if(b==sum){
        if(v[a].size()==0)return;
        X.push_back(v[a].back());
        v[a].pop_back();
    }
    else{
        if(v[a].size()==0)return;
        data d=v[a].back();v[a].pop_back();
        v[a].push_back(data(d.id,d.l,d.l+b-sum));
        X.push_back(data(d.id,d.l+b-sum,d.r));
    }
}

void query1(){
    int a,b,c,d;
    scanf("%d%d%d%d",&a,&b,&c,&d);
    a--;b--;c--;d--;

    vector<data>X,Y;

    div(a,b,X);
    div(c,d,Y);

    for(int i=(int)Y.size()-1;i>=0;i--)v[a].push_back(Y[i]);
    for(int i=(int)X.size()-1;i>=0;i--)v[c].push_back(X[i]);
}

void query2(){
    int a,b;char c;
    scanf("%d%d %c",&a,&b,&c);
    a--;b--;

    int cur,sum;
    get(a,b,cur,sum);

    int id=v[a][cur].id;
    int l=v[a][cur].l;
    int r=v[a][cur].r;
    s[id][b-sum+l]=c;
}

void update(int query){
    for(int i=0;i<n;i++)v[i].push_back(data(i,0,s[i].size()));

    for(int qry=0;qry<query;qry++){
        int type;scanf("%d",&type);
        if(type==1)query1();
        else query2();



    }



    for(int i=0;i<n;i++){
        _s[i]="";
        for(int j=0;j<v[i].size();j++){
            int id=v[i][j].id,l=v[i][j].l,r=v[i][j].r;
            _s[i]+=s[id].substr(l,r-l);
        }
    }

    for(int i=0;i<n;i++)s[i]=_s[i];
}
int main(){
    int q;
    scanf("%d%d",&n,&q);
    for(int i=0;i<n;i++){
        scanf("%s",latte);
        s[i]=latte;
    }

    for(int i=0;i<(q+B-1)/B;i++)update(min(B,q-i*B));

    for(int i=0;i<n;i++)printf("%s\n",s[i].c_str());
}
accuracy: 0.14285714285714285
time_ms: 10
memory_kb: 10424
final_rank: 19

code_snippet: #include<bits/stdc++.h>
using namespace std;
int B=1000;
char latte[2000001];
string s[100000],_s[100000];
int n;
struct data{
    int id,l,r;
    data(int a,int b,int c):id(a),l(b),r(c){}
};

vector<data>v[100000];

void get(int a,int b,int &cur,int &sum){
    sum=cur=0;
    while(cur<(int)v[a].size()&&sum+v[a][cur].r-v[a][cur].l<=b){
        sum+=v[a][cur].r-v[a][cur].l;
        cur++;
    }
}


void div(int a,int b,vector<data>&X){
    int cur,sum;
    get(a,b,cur,sum);
    for(int i=(int)v[a].size()-1;i>cur;i--){
        X.push_back(v[a].back());
        v[a].pop_back();
    }
    if(b==sum){
        X.push_back(v[a].back());
        v[a].pop_back();
    }
    else{
        data d=v[a].back();v[a].pop_back();
        v[a].push_back(data(d.id,d.l,d.l+b-sum));
        X.push_back(data(d.id,d.l+b-sum,d.r));
    }
}

void query1(){
    int a,b,c,d;
    scanf("%d%d%d%d",&a,&b,&c,&d);
    a--;b--;c--;d--;

    vector<data>X,Y;

    div(a,b,X);
    div(c,d,Y);

    for(int i=(int)Y.size()-1;i>=0;i--)v[a].push_back(Y[i]);
    for(int i=(int)X.size()-1;i>=0;i--)v[c].push_back(X[i]);
}

void query2(){
    int a,b;char c;
    scanf("%d%d %c",&a,&b,&c);
    a--;b--;

    int cur,sum;
    get(a,b,cur,sum);

    int id=v[a][cur].id;
    int l=v[a][cur].l;
    int r=v[a][cur].r;
    s[id][b-sum+l]=c;
}

void update(int query){
    for(int i=0;i<n;i++)v[i].push_back(data(i,0,s[i].size()));

    for(int qry=0;qry<query;qry++){
        int type;scanf("%d",&type);
        if(type==1)query1();
        else query2();



    }



    for(int i=0;i<n;i++){
        _s[i]="";
        for(int j=0;j<v[i].size();j++){
            int id=v[i][j].id,l=v[i][j].l,r=v[i][j].r;
            _s[i]+=s[id].substr(l,r-l);
        }
    }

    for(int i=0;i<n;i++)s[i]=_s[i];
}
int main(){
    int q;
    scanf("%d%d",&n,&q);
    for(int i=0;i<n;i++){
        scanf("%s",latte);
        s[i]=latte;
    }

    for(int i=0;i<(q+B-1)/B;i++)update(min(B,q-i*B));

    for(int i=0;i<n;i++)printf("%s\n",s[i].c_str());
}
accuracy: 0.14285714285714285
time_ms: 10
memory_kb: 10428
final_rank: 20