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 <cassert>
- const int N = 1e5 + 7, A = 26, C = 2, MOD = 998244353, bl = 1000;
- const long long INF = 1e18;
- using namespace std;
- using ll = long long;
- using ld = long double;
- const ld EPS = 1e-9;
- int a[N], n;
- struct Block {
- vector<int> elems;
- int cnt[N];
- int size;
- int count(int l, int r, int x) {
- if (r == size - 1 && l == 0) {
- return cnt[x];
- }
- int ans = 0;
- for (int i = l; i <= r; i++) {
- if (elems[i] == x) {
- ans++;
- }
- }
- return ans;
- }
- void clear() {
- for (int i = 0; i < size; i++) {
- cnt[elems[i]]--;
- elems[i] = 0;
- }
- elems.clear();
- size = 0;
- }
- void split(int r, Block* res) {
- res->clear();
- for (int i = r; i < size; i++) {
- cnt[elems[i]]--;
- res->cnt[elems[i]]++;
- }
- res->size = size - r;
- res->elems.resize(size - r);
- for (int i = r; i < size; i++) {
- res->elems[i - r] = elems[i];
- elems[i] = 0;
- }
- elems.resize(r);
- size = r;
- }
- };
- Block blocks[500];
- int CNT = 0;
- Block* nw() {
- if (CNT == 499) {
- cout << "ABOBA";
- exit(0);
- }
- return &blocks[CNT++];
- }
- struct SplitRebuildDecomp {
- vector<Block*> b;
- int size;
- void destroy() {
- for (int I = 0; I < b.size(); I++) {
- b[I]->clear();
- }
- b.clear();
- CNT = 0;
- }
- void build(int n) {
- size = n;
- int cnt = 0;
- destroy();
- for (int i = 0; i < n; i++) {
- if (i % bl == 0) {
- b.push_back(nw());
- }
- b[b.size() - 1]->cnt[a[i]]++;
- b[b.size() - 1]->elems.push_back(a[i]);
- b[b.size() - 1]->size++;
- }
- }
- void print(int n) {
- int i = 0;
- for (int I = 0; I < b.size(); I++) {
- auto u = b[I];
- for (int j = 0; j < u->size; j++) {
- a[i] = u->elems[j];
- i++;
- }
- }
- }
- void rebuild(int n) {
- print(n);
- build(n);
- }
- int FindL(int l) {
- int lft = 0;
- for (int i = 0; i < b.size(); i++) {
- if (lft == l) {
- return i;
- }
- lft += b[i]->size;
- }
- assert(false);
- }
- int FindR(int r) {
- int lft = 0;
- for (int i = 0; i < b.size(); i++) {
- if (lft + b[i]->size - 1 == r) {
- return i;
- }
- lft += b[i]->size;
- }
- assert(false);
- }
- void split(int r) {
- if (r == 0) {
- return;
- }
- int sz = 0;
- int i1 = -1;
- Block* newB = nw();
- for (int i = 0; i < b.size(); i++) {
- if (sz + b[i]->size == r) {
- CNT--;
- return;
- }
- if (sz + b[i]->size >= r) {
- b[i]->split(r - sz, newB);
- i1 = i + 1;
- break;
- }
- sz += b[i]->size;
- }
- for (i1; i1 < b.size(); i1++) {
- swap(newB, b[i1]);
- }
- b.push_back(newB);
- }
- void cyclic(int l, int r) {
- for (int i = r; i > l; i--) {
- swap(b[i], b[i - 1]);
- }
- }
- void cyc(int l, int r) {
- split(l);
- split(r);
- split(r + 1);
- l = FindL(l);
- r = FindR(r);
- cyclic(l, r);
- if (b.size() >= 400) {
- rebuild(size);
- }
- }
- int get(int l, int r, int k) {
- int lft = 0;
- int answ = 0;
- for (int i = 0; i < b.size(); i++) {
- int rgt = lft + b[i]->size - 1;
- int L = max(l, lft), R = min(r, rgt);
- if (L <= R) {
- answ += b[i]->count(L - lft, R - lft, k);
- }
- lft = rgt + 1;
- }
- return answ;
- }
- };
- SplitRebuildDecomp S;
- signed main() {
- #ifdef _DEBUG
- freopen("input.txt", "r", stdin);
- #else
- std::ios::sync_with_stdio(false);
- cin.tie(0);
- #endif
- cin >> n;
- for (int i = 0; i < n; i++) {
- cin >> a[i];
- }
- S.build(n);
- int q;
- cin >> q;
- int lastans = 0;
- for (int I = 0; I < q; I++) {
- int tp;
- cin >> tp;
- if (tp == 1) {
- int l, r;
- cin >> l >> r;
- l = (l + lastans - 1) % n + 1;
- r = (r + lastans - 1) % n + 1;
- l--;
- r--;
- if (l > r) {
- swap(l, r);
- }
- S.cyc(l, r);
- }
- else {
- int l, r, k;
- cin >> l >> r >> k;
- l = (l + lastans - 1) % n + 1;
- r = (r + lastans - 1) % n + 1;
- k = (k + lastans - 1) % n + 1;
- l--;
- r--;
- if (l > r) {
- swap(l, r);
- }
- lastans = S.get(l, r, k);
- cout << lastans << "\n";
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment