Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // clang-format off
- #define _CRT_SECURE_NO_WARNINGS
- #include <iostream>
- #include <iomanip>
- #include <bitset>
- #include <vector>
- #include <algorithm>
- #include <random>
- #include <map>
- #include <string>
- #include <set>
- #include <deque>
- #include <string>
- #include <cassert>
- #pragma GCC optimize("Ofast")
- using namespace std;
- const int N = 4e5 + 7, MOD = 1e9 + 7;
- const long long INF = 1e18;
- const long double EPS = 1e-9;
- int C, C2 = 430;
- int lb(int a) {
- return a & (-a);
- }
- vector<int> s;
- int bro[8];
- struct dq {
- int mas[4 * N], L , R;
- void clear() {
- L = 2*N;
- R = 2*N - 1;
- }
- int size() {
- return R - L + 1;
- }
- int front() {
- return mas[L];
- }
- int back() {
- return mas[R];
- }
- void pop_front() {
- L++;
- }
- void pop_back() {
- R--;
- }
- void push_front(int x) {
- L--;
- mas[L] = x;
- }
- void push_back(int x) {
- R++;
- mas[R] = x;
- }
- };
- struct Change {
- int tp; // seti push_back pop_back push_front pop_front
- int val;
- int* target;
- };
- struct Mo {
- dq indexes;
- int L, R;
- vector<Change> c;
- void process(Change a) {
- if (a.tp == 2) {
- indexes.push_back(a.val);
- }
- if (a.tp == 3) {
- indexes.pop_back();
- }
- if (a.tp == 4) {
- indexes.push_front(a.val);
- }
- if (a.tp == 5) {
- indexes.pop_front();
- }
- if (a.tp == 1) {
- *a.target = a.val;
- }
- }
- void otkat() {
- reverse(c.begin(), c.end());
- for (auto u : c) {
- process(u);
- }
- c.clear();
- }
- void init(int l) {
- c.clear();
- L = l;
- R = l;
- indexes.clear();
- indexes.push_back(s[l]);
- }
- void MoveL() {
- c.push_back({ 1, L,&L });
- L--;
- int b1 = int(s[L]);
- int b2 = bro[b1];
- if (indexes.size() == 0) {
- c.push_back({ 5, L, &L });
- indexes.push_front(b1);
- return;
- }
- int b = indexes.front();
- if (b == b2) {
- c.push_back({ 4, b, &L });
- indexes.pop_front();
- return;
- }
- c.push_back({ 5, L, &L });
- indexes.push_front(b1);
- return;
- }
- void MoveR() {
- c.push_back({ 1, R,&R });
- R++;
- int b1 = int(s[R]);
- int b2 = bro[b1];
- if (indexes.size() == 0) {
- c.push_back({ 3, R, &R });
- indexes.push_front(b1);
- return;
- }
- int b = indexes.back();
- if (b == b2) {
- c.push_back({ 2, b, &R });
- indexes.pop_back();
- return;
- }
- c.push_back({ 3, R, &R });
- indexes.push_back(b1);
- return;
- }
- bool get() {
- return indexes.size() == 0;
- }
- };
- Mo M;
- struct Fenwick {
- int f[N];
- void add(int i, int x) {
- for (i; i < N; i += lb(i)) {
- f[i] += x;
- }
- }
- int get(int i) {
- int answ = 0;
- for (i; i > 0; i -= lb(i)) {
- answ += f[i];
- }
- return answ;
- }
- int get(int l, int r) {
- return get(r) - get(l - 1);
- }
- };
- Fenwick cnt[8];
- struct Query {
- int t, l, r;
- int ind;
- };
- vector <Query> q, q2;
- int n, m;
- bool first_only = 1;
- bool ask_only = 1, ask[N];
- bool answ[N];
- char transf(char c) {
- if (c == '(') {
- c = 0;
- }
- if (c == ')') {
- c = 1;
- }
- if (c == '[') {
- c = 2;
- }
- if (c == ']') {
- c = 3;
- }
- if (c == '{') {
- c = 4;
- }
- if (c == '}') {
- c = 5;
- }
- if (c == '<') {
- c = 6;
- }
- if (c == '>') {
- c = 7;
- }
- return c;
- }
- bool stupid_check(int l, int r) {
- if ((r - l + 1) % 2) {
- return 0;
- }
- for (int i = 0; i < 8; i += 2) {
- if (cnt[i].get(l + 1, r + 1) != cnt[bro[i]].get(l + 1, r + 1)) {
- return 0;
- }
- }
- vector<int> indexes;
- indexes.clear();
- if (first_only) {
- return 1;
- }
- int total_sum = 0;
- for (int i = l; i <= r; i++) {
- auto u = s[i];
- int c = int(u);
- int b = bro[c];
- if (indexes.size() == 0 || indexes.back() != b) {
- indexes.push_back(c);
- }
- else {
- indexes.pop_back();
- }
- }
- return (indexes.size() == 0);
- }
- void stupid_solve() {
- for (int i = 0; i < m; i++) {
- if (q[i].t == 1) {
- cnt[s[q[i].l - 1]].add(q[i].l, -1);
- s[q[i].l - 1] = q[i].r;
- cnt[s[q[i].l - 1]].add(q[i].l, 1);
- }
- else {
- if ((q[i].r - q[i].l + 1) % 2) {
- cout << "No\n";
- continue;
- }
- if (stupid_check(q[i].l - 1, q[i].r - 1)) {
- cout << "Yes\n";
- }
- else {
- cout << "No\n";
- }
- }
- }
- }
- bool cmp(Query a, Query b) {
- if (a.l / C == b.l / C) {
- return a.r < b.r;
- }
- return a.l / C < b.l / C;
- }
- void solve_asks() {
- for (auto u : q) {
- if ((u.r - u.l + 1) % 2) {
- answ[u.ind] = 0;
- continue;
- }
- if (u.r - u.l + 1 <= C+1) {
- answ[u.ind] = stupid_check(u.l -1 , u.r - 1);
- continue;
- }
- q2.push_back({ u.t, u.l - 1, u.r - 1, u.ind });
- }
- sort(q2.begin(), q2.end(), cmp);
- for (int i = 0; i < q2.size(); i++) {
- if (i == 0 || q2[i].l / C != q2[i - 1].l / C) {
- M.init(C * (q2[i].l / C) + C - 1);
- }
- while (M.R < q2[i].r) {
- M.MoveR();
- }
- while (M.L > q2[i].l) {
- M.MoveL();
- }
- answ[q2[i].ind] = M.get();
- M.otkat();
- }
- for (int i = 0; i < m; i++) {
- if (answ[i]) {
- cout << "Yes\n";
- }
- else {
- cout << "No\n";
- }
- }
- }
- signed main() {
- #ifdef _DEBUG
- freopen("input.txt", "r", stdin);
- C2 = 2;
- #else
- std::ios::sync_with_stdio(false);
- cin.tie(0);
- #endif
- bro[0] = 1;
- bro[1] = 0;
- bro[2] = 3;
- bro[3] = 2;
- bro[4] = 5;
- bro[5] = 4;
- bro[6] = 7;
- bro[7] = 6;
- cin >> n;
- C = min(C2, n);
- s.resize(n);
- q.clear();
- for (int i = 0; i < n; i++) {
- char c;
- cin >> c;
- s[i] = transf(c);
- cnt[s[i]].add(i + 1, 1);
- if (s[i] > 1) {
- first_only = 0;
- }
- }
- cin >> m;
- for (int i = 0; i < m; i++) {
- int t;
- cin >> t;
- if (t == 1) {
- ask_only = 0;
- int ind;
- char c;
- cin >> ind >> c;
- c = transf(c);
- if (c > 1) {
- first_only = 0;
- }
- q.push_back({ t, ind, int(c), i });
- }
- else {
- int l, r;
- cin >> l >> r;
- ask[l] = 1;
- q.push_back({ t,l,r, i });
- }
- }
- if (first_only) {
- stupid_solve();
- return 0;
- }
- if (ask_only) {
- solve_asks();
- return 0;
- }
- if (n * m <= 100000000) {
- stupid_solve();
- return 0;
- }
- stupid_solve();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement