結果
| 問題 |
No.3239 Omnibus
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2025-08-15 23:41:01 |
| 言語 | C++23 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 667 ms / 10,000 ms |
| コード長 | 4,980 bytes |
| コンパイル時間 | 2,637 ms |
| コンパイル使用メモリ | 282,740 KB |
| 実行使用メモリ | 31,488 KB |
| 最終ジャッジ日時 | 2025-08-15 23:41:25 |
| 合計ジャッジ時間 | 18,239 ms |
|
ジャッジサーバーID (参考情報) |
judge6 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 1 |
| other | AC * 33 |
ソースコード
#include <bits/stdc++.h>
#define fi first
#define se second
#define rep(i,s,n) for (int i = (s); i < (n); ++i)
#define rrep(i,n,g) for (int i = (n)-1; i >= (g); --i)
#define all(a) a.begin(),a.end()
#define rall(a) a.rbegin(),a.rend()
#define len(x) (int)(x).size()
#define dup(x,y) (((x)+(y)-1)/(y))
#define pb push_back
#define eb emplace_back
#define Field(T) vector<vector<T>>
using namespace std;
using ll = long long;
using ull = unsigned long long;
template<typename T> using pq = priority_queue<T,vector<T>,greater<T>>;
using P = pair<int,int>;
template<class T>bool chmax(T&a,T b){if(a<b){a=b;return 1;}return 0;}
template<class T>bool chmin(T&a,T b){if(b<a){a=b;return 1;}return 0;}
template <typename S>
struct DynamicSegTree {
struct Node {
Node *l, *r;
ll idx;
S val, sum;
Node(S val_, ll p) : l(nullptr), r(nullptr), idx(p), val(val_), sum(val_) {}
void update() {
sum = val;
if (l) sum = l->sum + sum;
if (r) sum = sum + r->sum;
}
};
ll n;
Node* root;
const S e = S();
DynamicSegTree(ll _n) : n(_n), root(nullptr) {}
void set(ll p, S x) {
_set(root, 0, n, p, x);
}
S get(ll p) {
return _get(root, 0, n, p);
}
S prod(ll l, ll r) {
return _prod(root, 0, n, l, r);
}
S all_prod() {
if (!root) return e;
else return root->sum;
}
ll max_right(ll l, const function<bool(S)> &f) {
S x = e;
return _max_right(root, 0, n, l, x, f);
}
ll min_left(ll r, const function<bool(S)> &f) {
assert(r <= n);
assert(f(e));
S x = e;
return _min_left(root, 0, n, r, x, f);
}
private:
void _set(Node* &t, ll a, ll b, ll p, S x) {
if (!t) {
t = new Node(x, p);
return;
}
if (p == t->idx) {
t->val = x;
t->update();
return;
}
ll c = a + (b - a)/2;
if (p < c) {
if (t->idx < p) {
swap(t->idx, p);
swap(t->val, x);
}
_set(t->l, a, c, p, x);
} else {
if (t->idx > p) {
swap(t->idx, p);
swap(t->val, x);
}
_set(t->r, c, b, p, x);
}
t->update();
}
S _get(Node* &t, ll a, ll b, ll p) {
if (!t) return e;
if (p == t->idx) {
return t->val;
}
ll c = a + (b - a)/2;
if (p < c) {
return _get(t->l, a, c, p);
} else {
return _get(t->r, c, b, p);
}
}
S _prod(Node *&t, ll a, ll b, ll l, ll r) {
if (!t || b <= l || r <= a) return e;
if (l <= a && b <= r) return t->sum;
ll c = a + (b - a)/2;
return _prod(t->l, a, c, l, r) + ((l <= t->idx && t->idx < r) ? t->val : e) + _prod(t->r, c, b, l, r);
}
ll _max_right(Node *&t, ll a, ll b, ll l, S &x, const function<bool(S)> &f) const {
if (!t || b <= l) return n;
if (f(x + t->sum)) {
x = x + t->sum;
return n;
}
ll c = a + (b - a)/2;
ll res = _max_right(t->l, a, c, l, x, f);
if (res != n) return res;
if (l <= t->idx) {
x = x + t->val;
if (!f(x)) return t->idx;
}
return _max_right(t->r, c, b, l, x, f);
}
ll _min_left(Node *&t, ll a, ll b, ll r, S &x, const function<bool(S)> &f) const {
if (!t || r <= a) return 0;
if (f(t->sum + x)) {
x = t->sum + x;
return 0;
}
ll c = a + (b - a)/2;
ll res = _min_left(t->r, c, b, r, x, f);
if (res != 0) return res;
if (t->idx < r) {
x = t->val + x;
if (!f(x)) return t->idx + 1;
}
return _min_left(t->l, a, c, r, x, f);
};
};
struct S {
ll val; int cnt;
S(): val(0), cnt(0) {}
S(ll val, int cnt) : val(val), cnt(cnt) {}
friend S operator+(S a, S b) {
a.val += b.val, a.cnt += b.cnt;
return a;
}
};
int main() {
int n, q;
string s0;
cin >> n >> q >> s0;
vector<int> s(n);
rep(i,0,n) s[i] = s0[i]-'a';
int m = 17576;
vector<DynamicSegTree<S>> seg(m, DynamicSegTree<S>(n));
rep(i,0,n-2) {
int val = s[i]*676+s[i+1]*26+s[i+2];
seg[val].set(i, S{i, 1});
}
rep(i,0,q) {
int t;
cin >> t;
if (t == 1) {
int k; char c;
cin >> k >> c;
--k;
int x = c-'a';
if (k >= 2) {
int val = s[k-2]*676+s[k-1]*26+s[k];
seg[val].set(k-2, S());
int nval = s[k-2]*676+s[k-1]*26+x;
seg[nval].set(k-2, S(k-2, 1));
}
if (1 <= k && k < n-1) {
int val = s[k-1]*676+s[k]*26+s[k+1];
seg[val].set(k-1, S());
int nval = s[k-1]*676+x*26+s[k+1];
seg[nval].set(k-1, S(k-1, 1));
}
if (k < n-2) {
int val = s[k]*676+s[k+1]*26+s[k+2];
seg[val].set(k, S());
int nval = x*676+s[k+1]*26+s[k+2];
seg[nval].set(k, S(k, 1));
}
s[k] = x;
} else {
int l, r;
string u;
cin >> l >> r >> u;
--l;
if (r-l <= 2) {
cout << 0 << endl;
continue;
}
int a = (u[0]-'a')*676+(u[1]-'a')*26+(u[2]-'a');
S p = seg[a].prod(l, r-2);
ll ans = p.val-1LL*(l-1)*p.cnt;
cout << ans << endl;
}
}
return 0;
}