I recently read this blog and tried to implement this data structure in problem 455D - Serega and Fun mentioned in comments but it's getting WA and I can't seem to find any bug in my data structure implementation , I know asking you all to debug my code is not good but it's a desperate move :<(
303760090 In my implementation i havn't stored size of each block as in the problem we are swapping so there's never going to be too many or too less blocks
include <bits/stdc++.h>
include <ext/pb_ds/assoc_container.hpp>
include <ext/pb_ds/tree_policy.hpp>
namespace DEBUG_UTIL { using namespace std; void print(const char *x) {} void print(bool x) { cerr << (x ? "T" : "F"); } void print(char x) { cerr << ''' << x << '''; } void print(signed int x) { cerr << x; } void print(unsigned int x) { cerr << x; } void print(float x) { cerr << x; } void print(double x) { cerr << x; } void print(string x) { cerr << '"' << x << '"'; } template void print(bitset x) { cerr << x; } void print(vector x) { int f = 0; cerr << '{'; for (bool i : x) cerr << (f++ ? "," : "") << (i ? "T" : "F"); cerr << "}"; } template void print(T x) { int f = 0; cerr << '{'; for (auto i : x) cerr << (f++ ? "," : ""), print(i); cerr << "}"; } template void print(vector<vector> mat) { int f = 0; cerr << "{\n"; for (auto i : mat) cerr << (f++ ? ",\n" : ""), print(i); cerr << "}\n"; } template <typename T, size_t N> void print(T (&arr)[N]) { int f = 0; cerr << '{'; for (auto &i : arr) cerr << (f++ ? "," : ""), print(i); cerr << "}"; } template <typename F, typename S> void print(pair<F, S> x) { cerr << '('; print(x.first); cerr << ','; print(x.second); cerr << ')'; } template void print(priority_queue pq) { int f = 0; cerr << '{'; while (!pq.empty()) cerr << (f++ ? "," : ""), print(pq.top()), pq.pop(); cerr << "}"; } template void print(stack st) { int f = 0; cerr << '{'; while (!st.empty()) cerr << (f++ ? "," : ""), print(st.top()), st.pop(); cerr << "}"; } template void printer(const char *name, T &&head) { cerr << name << " = "; print(head); cerr << "]\n"; } template <typename T, typename... V> void printer(const char *names, T &&head, V &&...tail) { int b = 0, i = 0; while (names[i] != ',' || b != 0) { if (names[i] == '(') b++; else if (names[i] == ')') b--; i++; } cerr.write(names, i) << " = "; print(head); cerr << " ||"; printer(names + i + 1, tail...); } template void printerArr(const char *name, T arr[], int N) { cerr << name << " : {"; for (int i = 0; i < N; i++) cerr << (i ? "," : ""), print(arr[i]); cerr << "}]\n"; } }
ifndef ONLINE_JUDGE
define debug(...) std::cerr << LINE << ": [", DEBUG_UTIL::printer(#__VA_ARGS__, VA_ARGS)
define debugArr(arr, n) std::cerr << LINE << ": [", DEBUG_UTIL::printerArr(#arr, arr, n)
else
define debug(...)
define debugArr(arr, n)
endif
include <ext/pb_ds/assoc_container.hpp>
include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds; using namespace std;
define ordered_set tree<ll, null_type, less, rb_tree_tag, tree_order_statistics_node_update>
define ll long long
define ff first
define ss second
define pb push_back
define mp make_pair
define mii map<ll, ll>
define pii pair<ll, ll>
define vi vector
define vvi vector
define vb vector
define vpii vector
define pairMinHeap priority_queue<pii , vpii, greater >
define all(x) (x).begin(), (x).end()
define REP(i, a, b) for (ll i = a; i < b; i++)
define revREP(i,a,b) for (ll i = a ; i>b ; i--)
define MOD (ll)(1e9 + 7)
define mod (ll)998244353
void fast() { ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); } long long my_sqrt(long long a) { long long l=0,r=5000000001; while(r-l>1) { long long mid=(l+r)/2; if(1ll*mid*mid<=a)l=mid; else r=mid; } return l; } bool cmps(pii &a, pii &b) { return a.ss < b.ss; }
vector<deque> arr; vector<map<ll,ll>> fre; ll BLOCK_SIZE; void shift_right(ll l) { if(l>=arr.size()-1) return;
ll last_element = arr[l].back(); arr[l].pop_back(); fre[l][last_element]--; arr[l+1].push_front(last_element); fre[l+1][last_element]++; shift_right(l+1);
} void shift_left(ll l) { if(l>=arr.size()-1) return;
ll first_element = arr[l+1].front(); arr[l+1].pop_front(); fre[l+1][first_element]--; arr[l].push_back(first_element); fre[l][first_element]++; shift_left(l+1);
} void insert(ll pos,ll val) { ll idx = pos/BLOCK_SIZE; ll position = pos%BLOCK_SIZE; stack s; ll counter = position; while(counter--) { s.push(arr[idx].front()); arr[idx].pop_front(); } arr[idx].push_front(val); fre[idx][val]++; while(!s.empty()) { arr[idx].push_front(s.top()); s.pop(); } shift_right(idx); // Time Complexity : O(sqrt(n) + sqrt(n)) } ll remove(ll pos) { ll idx = pos/BLOCK_SIZE; ll position = pos%BLOCK_SIZE; stack s; ll counter = position; while(counter--) { s.push(arr[idx].front()); arr[idx].pop_front(); } // { ll removing_element = arr[idx].front(); arr[idx].pop_front(); fre[idx][removing_element]--; // } while(!s.empty()) { arr[idx].push_front(s.top()); s.pop(); } shift_left(idx); return removing_element; // Time Complexity : O(sqrt(n) + sqrt(n)) } ll get_first_k(ll l,ll k) { ll start_idx = l/BLOCK_SIZE; ll start_position = l%BLOCK_SIZE;
deque<ll> temp = arr[start_idx]; ll counter = start_position+1; ll res = 0; while(counter--) { if(temp.front() == k) res++; temp.pop_front(); } return res;
} ll get_last_k(ll l,ll k) { ll start_idx = l/BLOCK_SIZE; ll start_position = l%BLOCK_SIZE;
deque<ll> temp = arr[start_idx]; ll counter = start_position; ll res = 0; while(counter--) { if(temp.front() == k) res++; temp.pop_front(); } return fre[start_idx][k] - res;
} void solve(ll t) { ll n;cin>>n; BLOCK_SIZE = ceil(sqrt(n)); ll size = (n/BLOCK_SIZE)+1; arr.resize(size); fre.resize(size);
REP(i,0,n) { ll ele;cin>>ele; ll idx = (i/BLOCK_SIZE); arr[idx].push_back(ele); fre[idx][ele]++; } // debug(arr); // debug(fre); ll last_ans = 0; ll q;cin>>q; REP(i,0,q) { ll type;cin>>type; if(type == 1) { ll l,r;cin>>l>>r; l = (l + last_ans -1 + n)%n + 1; r = (r + last_ans -1 + n)%n + 1; l--; r--; ll removed_val = remove(r); insert(l,removed_val); } else { ll l,r,k;cin>>l>>r>>k; l = (l + last_ans -1 + n)%n + 1; r = (r + last_ans -1 + n)%n + 1; l--; r--; if( l > r) { l = l^r; r = l^r; l = l^r; } k = (k + last_ans -1 + n)%n + 1; ll end_idx = r/BLOCK_SIZE; ll end_position = r%BLOCK_SIZE; ll start_idx = l/BLOCK_SIZE; ll start_position = l%BLOCK_SIZE; if(start_idx == end_idx) { deque<ll> temp = arr[start_idx]; // remove first start_positon elements ll counter = start_position; while(counter--) temp.pop_front(); counter = end_position - start_position + 1; ll res = 0; while(counter--) { if(temp.front() == k) res++; temp.pop_front(); } last_ans = res; cout<<res<<"\n"; } else { // l -> Q(sqrt) ll first = get_last_k(l,k); ll second = 0; REP(i,start_idx+1,end_idx) { second += fre[i][k]; } ll third = get_first_k(r,k); // l+1 , r-1 // r -> O(aqrt) last_ans = first + second + third; cout<<last_ans<<"\n"; } } } return;
} int main() { fast(); #ifndef ONLINE_JUDGE freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout); #endif // ll t; // cin >> t; // REP(T,1,t+1) { solve(1); cout << endl; } return 0; }