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 integers a[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.
7
6 6 2 7 4 2 5
7
1 3 6
2 2 4 2
2 2 4 7
2 2 2 5
1 2 6
1 1 4
2 1 7 3
2
1
0
0
8
8 4 2 2 7 7 8 8
8
1 8 8
2 8 1 7
1 8 1
1 7 3
2 8 8 3
1 1 4
1 2 7
1 4 5
2
0
题目大意:给你一个长度为n的a数组,然后有2个操作
①输入l, r 把a[l],a[l+1]……,a[r]变成 a[r],a[l],a[l+1]……,a[r-1]
②输入l,r,v,求[l,r]中等于v的数有多少
且强制在线
思路:
用deque维护一个序列即可(md一个字母写错了debug一个下午加晚上,TAT)
不过我是很单纯的每次把deque里面的东西每次都取出来,所以跑了2000+ms,不过这个人的代码跑了500ms左右,大家如果要看可以学习一下:http://blog.csdn.net/blankcqk/article/details/38468729
我的代码:
//看看会不会爆int!数组会不会少了一维! //取物问题一定要小心先手胜利的条件 #include <bits/stdc++.h> using namespace std; #pragma comment(linker,"/STACK:102400000,102400000") #define LL long long #define ALL(a) a.begin(), a.end() #define pb push_back #define mk make_pair #define fi first #define se second #define haha printf("haha ") const int maxn = 1e5 + 5; int a[maxn]; deque<int> que[maxn]; int cnt[500][maxn]; int n, q; int belong[maxn], L[maxn], R[maxn], num, block; void build(){ block = sqrt(n); num = n / block; if (n % block) num++; for (int i = 1; i <= num; i++) L[i] = (i - 1) * block + 1, R[i] = i * block; R[num] = n; for (int i = 1; i <= n; i++) belong[i] = (i - 1) / block + 1; for (int i = 1; i <= num; i++) for (int j = L[i]; j <= R[i]; j++){ cnt[i][a[j]]++; que[i].push_back(a[j]); } } int tmp[500], t1[500], t2[500]; void update(int x, int y){ if (belong[x] == belong[y]){ int px = x - L[belong[x]] + 1;///在原来的里面的位置 int py = y - L[belong[y]] + 1; int t = 0; while (!que[belong[x]].empty()){ tmp[++t] = que[belong[x]].front(); que[belong[x]].pop_front(); } for (int i = 1; i <= t; i++){ if (i == px) que[belong[x]].push_back(tmp[py]); if (i == py) continue; que[belong[x]].push_back(tmp[i]); } return ; } int px = x - L[belong[x]] + 1;///在原来的里面的位置 int py = y - L[belong[y]] + 1; int tt1 = 0, tt2 = 0; while (!que[belong[x]].empty()){ t1[++tt1] = que[belong[x]].front(); que[belong[x]].pop_front(); } while (!que[belong[y]].empty()){ t2[++tt2] = que[belong[y]].front(); que[belong[y]].pop_front(); } for (int i = 1; i <= tt1; i++){ if (i == px) { que[belong[x]].push_back(t2[py]); cnt[belong[x]][t2[py]]++; } que[belong[x]].push_back(t1[i]); } for (int i = 1; i <= tt2; i++){ if (i == py) { cnt[belong[y]][t2[i]]--; continue; } que[belong[y]].push_back(t2[i]); } for (int i = belong[x] + 1; i <= belong[y]; i++){ int val = que[i - 1].back(); que[i - 1].pop_back(); cnt[i - 1][val]--; cnt[i][val]++; que[i].push_front(val); } } int query(int x, int y, int val){ int ans = 0; if (belong[x] == belong[y]){ int lb = x + 1 - L[belong[x]]; int rb = y + 1 - L[belong[y]];///修改了 int t = 0; while (!que[belong[x]].empty()){ tmp[++t] = que[belong[x]].front(); que[belong[x]].pop_front(); } for (int i = lb; i <= rb; i++) if (tmp[i] == val) ans++; for (int i = 1; i <= t; i++) que[belong[x]].push_back(tmp[i]); return ans; } ///对x的操作 int lb = x + 1 - L[belong[x]], rb = R[belong[x]] + 1 - L[belong[x]]; int t = 0; while (!que[belong[x]].empty()){ tmp[++t] = que[belong[x]].front(); que[belong[x]].pop_front(); } for (int i = lb; i <= rb; i++) if (tmp[i] == val) ans++; for (int i = 1; i <= t; i++) que[belong[x]].push_back(tmp[i]); //printf("ans = %d ", ans); ///对y的操作 lb = 1, rb = y + 1 - L[belong[y]]; t = 0; while (!que[belong[y]].empty()){ tmp[++t] = que[belong[y]].front(); que[belong[y]].pop_front(); } for (int i = lb; i <= rb; i++) if (tmp[i] == val) ans++; for (int i = 1; i <= t; i++) que[belong[y]].push_back(tmp[i]); //printf("ans = %d ", ans); ///对整体的操作 for (int i = belong[x] + 1; i < belong[y]; i++) ans += cnt[i][val]; return ans; } int main(){ cin >> n; for (int i = 1; i <= n; i++) scanf("%d", a + i); build(); cin >> q; int lastans = 0; for (int i = 1; i <= q; i++){ int ty, l, r, k; scanf("%d%d%d", &ty, &l, &r); l = (l + lastans - 1) % n + 1, r = (r + lastans - 1) % n + 1; if (l > r) swap(l, r); if(ty == 1){ if (l == r) continue; update(l, r); } else { scanf("%d", &k); k = (k + lastans - 1) % n + 1; printf("%d ", lastans = query(l, r, k)); } } return 0; }