0% found this document useful (0 votes)
3 views

message (1)

The document contains a C++ program that implements a solution for a problem involving string manipulation and queries using square root decomposition. It defines functions to build a data structure for efficient updates and queries, allowing for operations on a string of characters represented as integers. The program reads input, processes updates and queries, and outputs results based on specific conditions derived from the input string.

Uploaded by

pharminsi
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views

message (1)

The document contains a C++ program that implements a solution for a problem involving string manipulation and queries using square root decomposition. It defines functions to build a data structure for efficient updates and queries, allowing for operations on a string of characters represented as integers. The program reads input, processes updates and queries, and outputs results based on specific conditions derived from the input string.

Uploaded by

pharminsi
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 4

#include <bits/stdc++.

h>

#define task "BriantheCrab"

#define int long long


#define pii pair <int, int>
#define fi first
#define se second
#define szf sizeof
#define sz(s) (int)((s).size())

using namespace std;

template <class T> void mini (T &t, T f) {if (t > f) t = f;}


template <class T> void maxi (T &t, T f) {if (t < f) t = f;}

const int maxN = 1e5 + 5;


const int inf = 1e18 + 7;
const int mod = 1e9 + 7;
const int INF_V = 2e9;

int gn;
int va[maxN];
long long pw[30];
int a[maxN];

long long blk_s[maxN]; // Sqrt Decomposition: block_sum_p


int blk_m[maxN]; // Sqrt Decomposition: block_min_v
int blk_sz; // Block size
int num_blks; // Number of blocks

void build_sqrt() {
if (gn == 0) {
blk_sz = 1;
num_blks = 0;
return;
}
blk_sz = sqrt(gn);
if (blk_sz == 0) blk_sz = 1;
num_blks = (gn + blk_sz - 1) / blk_sz;

for (int i = 0; i < num_blks; ++ i ) {


blk_s[i] = 0;
blk_m[i] = INF_V;
}

for (int i = 1; i <= gn; ++ i ) {


int b_idx = (i - 1) / blk_sz;
blk_s[b_idx] += pw[va[i]];
mini(blk_m[b_idx], va[i]);
}
}

void upd_sqrt(int p, int nval) {


int b_idx = (p - 1) / blk_sz;
int oval = va[p];

if (oval == nval) return;


va[p] = nval;

blk_s[b_idx] -= pw[oval];
blk_s[b_idx] += pw[nval];

if (nval < blk_m[b_idx]) {


blk_m[b_idx] = nval;
} else if (oval == blk_m[b_idx]) {
blk_m[b_idx] = INF_V;
int L_blk = b_idx * blk_sz + 1;
int R_blk = min((b_idx + 1) * blk_sz, gn);
for (int i = L_blk; i <= R_blk; ++ i ) {
mini(blk_m[b_idx], va[i]);
}
}
}

pair<long long, int> qry_sqrt(int qL, int qR) {


if (qL > qR) return {0, INF_V};

long long cur_s = 0;


int cur_m = INF_V;

int i = qL;
while (i <= qR) {
int b_idx = (i - 1) / blk_sz;
int L_blk = b_idx * blk_sz + 1; // Start of current block
int R_blk = min((b_idx + 1) * blk_sz, gn); // End of current block

if (i == L_blk && R_blk <= qR) {


cur_s += blk_s[b_idx];
mini(cur_m, blk_m[b_idx]);
i = R_blk + 1;
} else {
cur_s += pw[va[i]];
mini(cur_m, va[i]);
++ i;
}
}
return {cur_s, cur_m};
}

void solve () {
int Q, X;
cin >> gn >> Q >> X;

pw[0] = 1;
for (int i = 1; i <= 26; ++ i ) {
pw[i] = pw[i-1] * 2;
}

string s_str;
cin >> s_str;

for (int i = 1; i <= gn; ++ i ) {


va[i] = s_str[i-1] - 'a';
}
build_sqrt();

for (int qi = 0; qi < Q; ++ qi ) {


char type;
cin >> type;
if (type == '!') {
int p_idx;
char ch;
cin >> p_idx >> ch;
int nval = ch - 'a';
upd_sqrt(p_idx, nval);
} else {
int qL, qR;
long long TQ;
cin >> qL >> qR >> TQ;

int len = qR - qL + 1;

if (len == 1) {
long long PL = pw[va[qL]];
if (TQ == PL) {
cout << "YES\n";
} else {
cout << "NO\n";
}
} else {
long long PR = pw[va[qR]];
long long PRm1 = pw[va[qR-1]];

if (len == 2) {
if (TQ == (PR - PRm1)) {
cout << "YES\n";
} else {
cout << "NO\n";
}
} else {
long long targetT = TQ + PRm1 - PR;

pair<long long, int> res_W = qry_sqrt(qL, qR - 2);


long long sumW = res_W.fi;
int minV = res_W.se;

// For len >= 3, the range [qL, qR-2] is non-empty, so minV


should be valid.
// And pw[minV] will be >= 1.
long long gW = pw[minV];

if (targetT % gW != 0) {
cout << "NO\n";
} else {
long long sumWg = sumW / gW;
long long targetTg = targetT / gW;

if (abs(targetTg) > sumWg || (sumWg - targetTg) % 2 != 0) {


cout << "NO\n";
} else {
cout << "YES\n";
}
}
}
}
}
}
}

signed main () {
cin.tie (nullptr) -> sync_with_stdio (false);
if (fopen (task".inp", "r")) {
freopen (task".inp", "r", stdin);
freopen (task".out", "w", stdout);
}
int t = 1;
//cin >> t;
while (t --) {
solve ();
}
return 0;
}

You might also like