Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma comment(linker, "/stack:200000000"]
- #pragma GCC optimize("Ofast"]
- #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native"]
- #include<iostream>
- #include<cmath>
- #include<algorithm>
- #include<vector>
- #include<map>
- #include<unordered_set>
- #include<unordered_map>
- #include<map>
- #include<algorithm>
- #include<queue>
- #include<stack>
- #include<cstdio>
- #include<random>
- #include<cassert>
- #include<sstream>
- #include<set>
- using namespace std;
- const int maxN = 1e5 + 10;
- const int base = 255;
- const int mod = 1791791791;
- int n, q;
- string s;
- int pows[maxN];
- int pref[maxN];
- void init(){
- pows[0] = 1;
- pref[0] = 1;
- for(int i = 1; i < maxN; i++){
- pows[i] = (1ll * pows[i - 1] * base) % mod;
- pref[i] = (1ll * pref[i - 1] + pows[i]) % mod;
- }
- }
- struct node{
- int add, sz;
- pair<int, int> h;
- node(int h = 0, int sz = 0, int add = -1){
- this->h = {h, h};
- this->add = add;
- this->sz = sz;
- }
- pair<int, int> getHash(){
- if(add > -1){
- int pans = (1ll * add * pref[sz - 1]) % mod;
- return {pans, pans};
- }else return h;
- }
- };
- struct segmentTree{
- node t[4 * maxN];
- segmentTree(){
- build();
- }
- void push(int v){
- if(t[v].add == -1)return;
- t[2 * v + 1].add = t[v].add;
- t[2 * v + 2].add = t[v].add;
- t[v].add = -1;
- }
- void merge(int v, int tl, int tr){
- int mid = (tl + tr) / 2;
- int szR = tr - mid, szL = mid - tl;
- t[v].h.first = ((1ll * t[2 * v + 1].getHash().first * pows[szR]) % mod + t[2 * v + 2].getHash().first) % mod;
- t[v].h.second = ((1ll * t[2 * v + 2].getHash().second * pows[szL]) % mod + t[2 * v + 1].getHash().second) % mod;
- }
- void build(int v = 0, int tl = 0, int tr = n){
- if(tr - tl == 1)t[v] = node(s[tl], 1, -1);
- else{
- int mid = (tl + tr) / 2;
- build(2 * v + 1, tl, mid);
- build(2 * v + 2, mid, tr);
- t[v].sz = tr - tl;
- merge(v, tl, tr);
- }
- }
- void change(int L, int R, int x, int v = 0, int tl = 0, int tr = n){
- if(R <= tl || L >= tr || tr - tl < 1)return;
- else if(L <= tl && tr <= R)t[v].add = x;
- else{
- push(v);
- int mid = (tl + tr) / 2;
- change(L, R, x, 2 * v + 1, tl, mid);
- change(L, R, x, 2 * v + 2, mid, tr);
- merge(v, tl, tr);
- }
- }
- node get(int L, int R, int v = 0, int tl = 0, int tr = n){
- if(L <= tl && tr <= R)return t[v];
- else{
- push(v);
- int mid = (tl + tr) / 2;
- node ans;
- if(L >= mid)ans = get(L, R, 2 * v + 2, mid, tr);
- else if(R <= mid)ans = get(L, R, 2 * v + 1, tl, mid);
- else{
- node l = get(L, R, 2 * v + 1, tl, mid);
- node r = get(L, R, 2 * v + 2, mid, tr);
- ans.h.first = ((1ll * l.getHash().first * pows[r.sz]) % mod + r.getHash().first) % mod;
- ans.h.second = ((1ll * r.getHash().second * pows[l.sz]) % mod + l.getHash().second) % mod;
- ans.sz = l.sz + r.sz;
- }
- merge(v, tl, tr);
- return ans;
- }
- }
- };
- signed main(){
- ios_base::sync_with_stdio(0);
- cin.tie(0);
- cout.tie(0);
- init();
- cin >> n >> q;
- cin >> s;
- segmentTree t;
- for(int i = 0; i < q; i++){
- string s; cin >> s;
- if(s[0] == 'a'){
- int l, r; cin >> l >> r; l--;
- node ans = t.get(l, r);
- if(ans.getHash().first == ans.getHash().second)cout << "YES\n";
- else cout << "NO\n";
- }else{
- int l, r; char c; cin >> l >> r >> c; l--;
- t.change(l, r, c);
- }
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement