// compile: make data
// run: ./data < data.in
#include <bits/stdc++.h>
using namespace std;
#pragma GCC optimize("O3,unroll-loops")
#pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt")
#ifdef LOCAL
#include <debug/codeforces.h>
#define debug(x...) _debug_print(#x, x);
#define Debug(x...) _debug_print_format(#x, x);
std::ifstream terminal("/dev/tty");
#define PP cerr<<"\033[1;30mpause...\e[0m",terminal.ignore();
#else
#define debug(x...)
#define Debug(x...)
#define PP
#endif
template<typename...Args> void print_(Args...args){((cout<<args<<" "),...)<<endl;}
#define VI vector<int>
#define VII vector<vector<int>>
#define VIII vector<vector<vector<int>>>
#define rep(i,a,b) for(int i=(a);i<(int)(b);++i)
#define sz(v) ((int)(v).size())
#define print(...) print_(__VA_ARGS__);
#define FIND(a, x) ((find(a.begin(),a.end(),(x))!=a.end())?1:0)
#define cmin(x,...) x=min({(x), __VA_ARGS__})
#define cmax(x,...) x=max({(x), __VA_ARGS__})
#define INTMAX (int)(9223372036854775807)
#define INF (int)(1152921504606846976)
#define NaN (int)(0x8b88e1d0595d51d1)
#define double long double
#define int long long
#define uint unsigned long long
#define MAXN 200010
#define P1 998244353
#define P2 1000000007
template <class T> struct segtree {
struct node {
int l, r;
T val;
node *ch[2];
};
int cnt = 0;
T DEFAULT_VALUE;
node *newnode(int l, int r) {
node *x = (l==r) ? &datalist[l] : &datalist[cnt++];
x->l = l, x->r = r;
x->ch[0] = x->ch[1] = nullptr;
x->val.size = r - l + 1;
return x;
}
vector<int> a;
vector<node> datalist;
node *root;
segtree(vector<int> arr) {
cnt = sz(arr);
a = arr, build();
}
void pushup(node *x) {
if (!x) return;
if (!x->ch[0] && !x->ch[1]) return;
if (x->ch[0] && x->ch[1]) x->val = x->ch[0]->val + x->ch[1]->val;
else x->val = x->ch[!x->ch[0]]->val;
}
T query(int ql, int qr) {
if (qr - ql < 10) {
T res = DEFAULT_VALUE;
rep(i, ql, qr+1) res = res + datalist[i].val;
return res;
}
function<T(node*)> dfs = [&](node *x) -> T {
if (!x) return DEFAULT_VALUE;
if (ql > x->r || qr < x->l) return DEFAULT_VALUE;
if (x->l >= ql && x->r <= qr) return x->val;
return dfs(x->ch[0]) + dfs(x->ch[1]);
};
return dfs(root);
}
template <typename U> void modify(int q, U val) {
function<void(node*)> dfs = [&](node *x) -> void {
if (q > x->r || q < x->l) return;
if (x->l >= q && x->r <= q) {
x->val.update(val);
return;
}
dfs(x->ch[0]), dfs(x->ch[1]);
pushup(x);
};
dfs(root);
}
void build() {
datalist.resize(sz(a) * 2);
function<node*(int, int)> dfs = [&](int l, int r) {
node *x = newnode(l, r);
if (r > l) x->ch[0] = dfs(l, (l+r) >> 1), x->ch[1] = dfs(((l+r)>>1) + 1, r);
else x->val.set(a[l]);
pushup(x);
return x;
};
root = dfs(0, sz(a)-1);
}
void graphviz_dump(string filename = "graph.dot") {
FILE *f = fopen(filename.c_str(), "w");
fprintf(f, "digraph {\n");
rep(i, 0, cnt) {
node *x = &datalist[i];
fprintf(f, " %lld;\n");
}
rep(i, 0, cnt) {
node *x = &datalist[i];
if (x->ch[0]) fprintf(f, " %lld -> %ld;\n", i, x->ch[0] - &datalist[0]);
if (x->ch[1]) fprintf(f, " %lld -> %ld;\n", i, x->ch[1] - &datalist[0]);
}
fprintf(f, "}\n");
}
};
vector<int> pow1, pow2;
int32_t main() {
ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
struct value {
int h1 = 0, h2 = 0;
int size = 0;
value operator+(const value &rhs) const {
value lhs = *this;
value res;
res.h1 = (lhs.h1 * pow1[rhs.size] + rhs.h1) % P1;
res.h2 = (lhs.h2 * pow2[rhs.size] + rhs.h2) % P2;
res.size = lhs.size + rhs.size;
return res;
}
void set(int rhs) {
h1 = h2 = rhs;
}
void update(int val) {
h1 = h2 = val;
}
};
int n, q; cin >> n >> q;
pow1.resize(n), pow2.resize(n);
pow1[0] = pow2[0] = 1;
rep(i, 1, n) pow1[i] = pow1[i-1] * 26 % P1, pow2[i] = pow2[i-1] * 26 % P2;
vector<int> a(n), b(n);
string s; cin >> s;
rep(i, 0, s.length()) a[i] = s[i] - 'a', b[i] = s[n-i-1] - 'a';
segtree<value> t(a), tinv(b);
while (q--) {
int op; cin >> op;
if (op == 1) {
int x; string c; cin >> x >> c; --x;
t.modify(x, c[0] - 'a');
tinv.modify(n-x-1, c[0] - 'a');
}
else {
int l, r; cin >> l >> r; --l, --r;
value hs = t.query(l, r);
value hsinv = tinv.query(n-r-1, n-l-1);
printf("%s\n", hs.h1 == hsinv.h1 && hs.h2 == hsinv.h2 ? "YES" : "NO");
}
}
return 0;
}
MCW7733 is cool. Easy to navigate and loads of games. Could improve on the bonuses, but overall a solid site. mcw7733
If you’re after an experience, Stray is worth it! Found the game through strayvideojuego. Story is really engaging, and the graphics are awesome. strayvideojuego helped me find this!
Alright, alright, phil168vip… I see you. Seems like a decent VIP option. Gonna need to dive a little deeper to see what’s what, but it’s got my attention. Anyone else tried it out? Let me know what you think! phil168vip
Logging in is completely hassle free and I love the personalized dashboard that tracks my betting history. The live dealer tables have great camera angles and professional croupiers. It feels like having a premium casino lounge right at my fingertips. panalokologin
Just signed up and I am already impressed by how welcoming the whole community feels. Customer support actually answers on time and the live dealer tables are running without a hitch. Great vibes for anyone looking to relax and play. vnkuvip
The slot collection on this site is absolutely amazing with some huge jackpots waiting to be hit. I love how they update the games regularly so the gameplay never gets boring. Worth a spin qqmacanslot