Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <vector>
- #include <stack>
- #include <algorithm>
- #include <cmath>
- #include <set>
- #include <map>
- #include <bitset>
- #include <string>
- #include <deque>
- #include <queue>
- #include <unordered_set>
- #include <unordered_map>
- #define pb push_back
- #define ll long long
- #define ld long double
- #define all(a) a.begin(), a.end()
- using namespace std;
- //tg: @galebickosikasa
- vector<string> STRINGS_BEACH;
- struct Tree{
- Tree* left;
- Tree* right;
- int priority;
- uint32_t size;
- // vector<int> assign;
- // vector<int> goo;
- bitset<1000001> assign, goo;
- Tree(){
- left = right = nullptr;
- size = 1;
- priority = rand();
- }
- };
- uint32_t get_size(Tree* t){
- if (t == nullptr){
- return 0;
- }
- return t->size;
- }
- void push(Tree* t){
- if (!t->assign.count()){
- return;
- }
- t->goo |= t->assign;
- if (t->left != nullptr){
- t->left->assign |= t->assign;
- }
- if (t->right != nullptr){
- t->right->assign |= t->assign;
- }
- t->assign.reset();
- }
- void render(Tree* t){
- if (t == nullptr){
- return;
- }
- t->size = 1 + get_size(t->left) + get_size(t->right);
- }
- pair<Tree*, Tree*> split(Tree* t, int k){
- pair<Tree*, Tree*> ptt = {nullptr, nullptr};
- if (t == nullptr){
- return ptt;
- }
- push(t);
- if (get_size(t->left) >= k){
- ptt = split(t->left, k);
- t->left = ptt.second;
- ptt.second = t;
- } else{
- ptt = split(t->right, k - get_size(t->left) - 1);
- t->right = ptt.first;
- ptt.first = t;
- }
- render(t);
- return ptt;
- }
- Tree* merge(Tree* l, Tree* r){
- if (l == nullptr){
- return r;
- } else if (r == nullptr){
- return l;
- } else if (l->priority >= r->priority){
- push(l);
- l->right = merge(l->right, r);
- render(l);
- return l;
- } else{
- push(r);
- r->left = merge(l, r->left);
- render(r);
- return r;
- }
- }
- Tree* add(Tree* t, Tree* a, int i){
- auto ptt = split(t, i - 1);
- ptt.first = merge(ptt.first, a);
- return merge(ptt.first, ptt.second);
- }
- Tree* add(Tree* t, int i){
- Tree* a = new Tree();
- return add(t, a, i);
- }
- void collect_num(Tree* t, int i, bitset<1000001>& a){
- if (get_size(t->left) + 1 == i){
- a |= t->goo;
- a |= t->assign;
- return;
- }
- if (get_size(t->left) >= i){
- collect_num(t->left, i, a);
- } else{
- collect_num(t->right, i - get_size(t->left) - 1, a);
- }
- a |= t->assign;
- }
- int main(){
- ios_base::sync_with_stdio(false);
- cout.tie(nullptr);
- cin.tie(nullptr);
- Tree* root = nullptr;
- int n, m;
- cin >> n >> m;
- bitset<1000001> tmp;
- for (int i = 0; i < n; ++i){
- root = add(root, i + 1);
- }
- for (int i = 0; i < m; ++i){
- int w;
- cin >> w;
- if (w == 1){
- int l, r;
- string s;
- cin >> l >> r >> s;
- STRINGS_BEACH.pb(s);
- auto ptt1 = split(root, l - 1);
- auto ptt2 = split(ptt1.second, r - l + 1);
- ptt2.first->assign[STRINGS_BEACH.size() - 1] = true;
- ptt1.second = merge(ptt2.first, ptt2.second);
- root = merge(ptt1.first, ptt1.second);
- } else{
- int a, x, y;
- cin >> a >> x >> y;
- collect_num(root, a, tmp);
- int j = tmp._Find_first();
- while (STRINGS_BEACH[j].size() < x){
- x -= STRINGS_BEACH[j].size(), y -= STRINGS_BEACH[j].size();
- tmp[j] = false;
- j = tmp._Find_first();
- }
- if (y <= STRINGS_BEACH[j].size()){
- for (int k = x - 1; k < y; ++k){
- cout << STRINGS_BEACH[j][k];
- }
- } else{
- for (int k = x - 1; k < STRINGS_BEACH[j].size(); ++k){
- cout << STRINGS_BEACH[j][k];
- }
- y -= STRINGS_BEACH[j].size();
- tmp[j] = false;
- j = tmp._Find_first();
- while (STRINGS_BEACH[j].size() < y){
- cout << STRINGS_BEACH[j];
- y -= STRINGS_BEACH[j].size();
- tmp[j] = false;
- j = tmp._Find_first();
- }
- for (int k = 0; k < y; ++k){
- cout << STRINGS_BEACH[j][k];
- }
- }
- cout << '\n';
- tmp.reset();
- }
- }
- }
- /*
- 4 4
- 1 2 2 two
- 1 2 3 aa
- 2 3 1 1
- 2 2 1 4
- 3 6
- 1 1 2 ab
- 1 2 3 cd
- 2 2 2 4
- 2 3 1 2
- 1 1 3 xyzu
- 2 1 2 5
- */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement