CF455D. Serega and Fun
Serega loves fun. However, everyone has fun in the unique manner. Serega has fun by solving query problems. One day Fedor came up with such a problem.
You are given an array a consisting of n positive integers and queries to it. The queries can be of two types:
- Make a unit cyclic shift to the right on the segment from l to r (both borders inclusive). That is rearrange elements of the array in the following manner:
a[l], a[l + 1], ..., a[r - 1], a[r] → a[r], a[l], a[l + 1], ..., a[r - 1]. - Count how many numbers equal to k are on the segment from l to r (both borders inclusive).
Fedor hurried to see Serega enjoy the problem and Serega solved it really quickly. Let's see, can you solve it?
The first line contains integer n (1 ≤ n ≤ 105) — the number of elements of the array. The second line contains n integersa[1], a[2], ..., a[n] (1 ≤ a[i] ≤ n).
The third line contains a single integer q (1 ≤ q ≤ 105) — the number of queries. The next q lines contain the queries.
As you need to respond to the queries online, the queries will be encoded. A query of the first type will be given in format: 1 l'i r'i. A query of the second type will be given in format: 2 l'i r'i k'i. All the number in input are integer. They satisfy the constraints: 1 ≤ l'i, r'i, k'i ≤ n.
To decode the queries from the data given in input, you need to perform the following transformations:
Where lastans is the last reply to the query of the 2-nd type (initially, lastans = 0). If after transformation li is greater than ri, you must swap these values.
For each query of the 2-nd type print the answer on a single line.
分块搞搞。。比较坑,不好调试。
#include <bits/stdc++.h> using namespace std; const int maxn = 1e5 + 100; const int maxs = 800; const int maxb = maxn / maxs + 100; const int maxr = 1000; const int maxv = maxs + maxr + 100; const bool D = false; struct Block { int size, ele[maxv], cnt[maxn], vals[maxv], tot; Block() { size = tot = 0; memset(cnt, 0, sizeof cnt); memset(vals, 0, sizeof vals); } void append(const int &val) { ++cnt[val]; vals[++tot] = val; ele[++size] = val; } void init() { for(int i = 1; i <= tot; ++i) cnt[vals[i]] = 0; tot = size = 0; } } b[maxb]; int a[maxn], t[maxn], n, q, nb; void print() { if(D) { printf("%d\n", nb); for(int i = 1; i <= nb; ++i) { for(int j = 1; j <= b[i].size; ++j) printf("%d ", b[i].ele[j]); puts(""); } } } void build() { nb = 0; for(int i = 1; i <= n; i += maxs) { ++nb; for(int up = min(n, i + maxs - 1), j = i; j <= up; ++j) b[nb].append(a[j]); } } void re_build() { n = 0; for(int i = 1; i <= nb; ++i) { for(int j = 1; j <= b[i].size; ++j) t[++n] = b[i].ele[j]; b[i].init(); } for(int i = 1; i <= n; ++i) a[i] = t[i]; build(); } int erase(int pos) { for(int i = 1, sum = 0; i <= nb; ++i) { sum += b[i].size; if(pos <= sum) { sum -= b[i].size; pos -= sum; int ret = b[i].ele[pos]; for(int j = pos + 1; j <= b[i].size; ++j) b[i].ele[j - 1] = b[i].ele[j]; --b[i].cnt[ret]; --b[i].size; return ret; } } return 0; } void insert(int pos, int val) { for(int i = 1, sum = 0; i <= nb; ++i) { sum += b[i].size; if(pos <= sum) { sum -= b[i].size; pos -= sum; ++b[i].size; for(int j = b[i].size; pos < j; --j) b[i].ele[j] = b[i].ele[j - 1]; b[i].vals[++b[i].tot] = val; ++b[i].cnt[val]; b[i].ele[pos + 1] = val; return ; } } } void shift(int l, int r) { if(l == r) return ; insert(l - 1, erase(r)); } int count(int pos, int val) { if(pos <= 0) return 0; int ret = 0; for(int i = 1, sum = 0; i <= nb; ++i) { sum += b[i].size; if(pos <= sum) { sum -= b[i].size; pos -= sum; for(int j = 1; j <= pos; ++j) ret += (b[i].ele[j] == val); return ret; } else { ret += b[i].cnt[val]; } } return 0; } int main() { scanf("%d", &n); for(int i = 1; i <= n; scanf("%d", &a[i]), ++i); build(); print(); scanf("%d", &q); for(int T = 1, last_ans = 0, type, l, r, val; T <= q; ++T) { scanf("%d%d%d", &type, &l, &r); l = (last_ans + l - 1) % n + 1, r = (last_ans + r - 1) % n + 1; if(r < l) swap(l, r); if(type == 1) { shift(l, r); } else { scanf("%d", &val); val = (last_ans + val - 1) % n + 1; last_ans = count(r, val) - count(l - 1, val); printf("%d\n", last_ans); } if(T % maxr == 0) re_build(); } return 0; }