Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #ifdef LOCAL
- #include <iostream>
- #include <fstream>
- #include <iomanip>
- #include <random>
- #include <vector>
- #include <queue>
- #include <stack>
- #include <set>
- #include <map>
- #else
- #pragma GCC optimize("Ofast,unroll-loops")
- #include <bits/stdc++.h>
- #define cerr if (false) cerr
- #define endl '\n'
- #endif
- #define fi first
- #define se second
- #define sz(a) ((int)(a).size())
- #define all(a) (a).begin(), (a).end()
- #define lsb(x) (x & (-x))
- #define YES cout << "yes" << endl
- #define NO cout << "no" << endl
- using namespace std;
- template <typename T>
- bool ckmax(T &a, T b) { return a < b ? a = b, true : false; }
- template <typename T>
- bool ckmin(T &a, T b) { return a > b ? a = b, true : false; }
- using ll = long long;
- using pii = pair<int, int>;
- const int NMAX = 3e5+5;
- const int MOD = 869691499;
- const int A = 59;
- int n, q;
- char a[NMAX];
- int lgpow(int a, int n) {
- if (n == 0) return 1;
- if (n & 1) return 1ll * a * lgpow(a, n ^ 1) % MOD;
- int p = lgpow(a, n >> 1);
- return 1ll * p * p % MOD;
- }
- struct Treap {
- char val;
- int pr, size;
- int hsh;
- Treap *l, *r;
- Treap(): val(0), pr(0), size(0), hsh(0), l(nullptr), r(nullptr) { }
- Treap(char _val): val(_val), size(1), hsh(1ll * (_val - 'a' + 1) * A % MOD), l(nullptr), r(nullptr) {
- static mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
- pr = int(rng());
- }
- };
- ostream &operator<<(ostream &out, Treap *t) {
- function<void(Treap*)> dfs = [&](Treap *t) {
- if (!t) return;
- dfs(t->l);
- out << t->val;
- dfs(t->r);
- };
- dfs(t);
- return out;
- }
- int size(Treap *a) { return a ? a->size : 0; }
- int hsh(Treap *a) { return a ? a->hsh : 0; }
- Treap *treap_update(Treap *a) {
- if (!a) return nullptr;
- a->size = size(a->l) + size(a->r) + 1;
- a->hsh = hsh(a->l);
- int p = lgpow(A, size(a->l) + 1);
- a->hsh = 1ll * (1ll * a->hsh + 1ll * (a->val - 'a' + 1) * p) % MOD;
- a->hsh = 1ll * (1ll * a->hsh + 1ll * hsh(a->r) * p) % MOD;
- return a;
- }
- Treap *join(Treap *a, Treap *b) {
- if (!a || !b) return a ? a : b;
- if (a->pr > b->pr) return a->r = join(a->r, b), treap_update(a);
- return b->l = join(a, b->l), treap_update(b);
- }
- Treap *join(vector<Treap*> treaps) {
- if (treaps.empty()) return nullptr;
- Treap *ret = treaps[0];
- for (int i = 1; i < sz(treaps); i++)
- ret = join(ret, treaps[i]);
- return ret;
- }
- pair<Treap*, Treap*> split(Treap *a, int pos) {
- if (!a) return { nullptr, nullptr };
- if (size(a->l) + 1 <= pos) {
- auto [ l, r ] = split(a->r, pos - size(a->l) - 1);
- a->r = l;
- return { treap_update(a), r };
- }
- auto [ l, r ] = split(a->l, pos);
- a->l = r;
- return { l, treap_update(a) };
- }
- tuple<Treap*, Treap*, Treap*> split_segment(Treap *treap, int l, int r) {
- auto [ a, suff ] = split(treap, l - 1);
- auto [ mid, b ] = split(suff, r - l + 1);
- return { a, mid, b };
- }
- Treap *remove_segment(Treap *treap, int l, int r) {
- auto [ a, mid, b ] = split_segment(treap, l, r);
- return join(a, b);
- }
- Treap *insert(Treap *treap, int pos, char val) {
- auto [ l, r ] = split(treap, pos - 1);
- return join({ l, new Treap(val), r });
- }
- bool query(Treap *t1, Treap *t2, int l, int r) {
- auto [ left1, mid1, right1 ] = split_segment(t1, l, r);
- auto [ left2, mid2, right2 ] = split_segment(t2, n - r + 1, n - l + 1);
- bool ret = mid1->hsh == mid2->hsh;
- join({ left1, mid1, right1 });
- join({ left2, mid2, right2 });
- return ret;
- }
- void read() {
- cin >> n >> q >> (a + 1);
- }
- void solve() {
- Treap *t1 = new Treap(a[1]);
- Treap *t2 = new Treap(a[n]);
- for (int i = 2; i <= n; i++) {
- t1 = join(t1, new Treap(a[i]));
- t2 = join(t2, new Treap(a[n - i + 1]));
- }
- for (int i = 1; i <= q; i++) {
- char c;
- int t, l, r, p;
- cin >> t;
- if (t == 1) {
- cin >> l >> r;
- t1 = remove_segment(t1, l, r);
- t2 = remove_segment(t2, n - r + 1, n - l + 1);
- n -= r - l + 1;
- } else if (t == 2) {
- cin >> c >> p;
- t1 = insert(t1, p, c);
- t2 = insert(t2, n - p + 2, c);
- n++;
- } else {
- cin >> l >> r;
- if (query(t1, t2, l, r)) YES;
- else NO;
- }
- }
- }
- signed main() {
- #ifdef LOCAL
- freopen("input.txt", "r", stdin);
- #endif
- ios_base::sync_with_stdio(false);
- cin.tie(0);
- cout.tie(0);
- read();
- solve();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement