CodeForces - 455D

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:

  1. 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].
  2. 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?


Input

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:

li = ((l'i + lastans - 1) mod n) + 1; ri = ((r'i + lastans - 1) mod n) + 1; ki = ((k'i + lastans - 1) mod n) + 1.

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.

Output

For each query of the 2-nd type print the answer on a single line.

Examples
Input
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
Output
2
1
0
0
Input
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
Output
2
0
分块+双端队列
每次更新对每块进行操作:
1.中间的整块:取出最后一个放入下一块的前端;
2.两端的块:左边的块放入给定右边界位置的数字,右端的块删除给定右边界位置的数字
每次询问:
中间的整块直接查询,两边的块遍历可访问的位置;
  1 #include <cstdio>
  2 #include <stack>
  3 #include <cmath>
  4 #include <queue>
  5 #include <string>
  6 #include <queue>
  7 #include <cstring>
  8 #include <iostream>
  9 #include <algorithm>
 10 
 11 #define lid id<<1
 12 #define rid id<<1|1
 13 #define closein cin.tie(0)
 14 #define scac(a) scanf("%c",&a)
 15 #define scad(a) scanf("%d",&a)
 16 #define print(a) printf("%d\n",a)
 17 #define debug printf("hello world")
 18 #define form(i,n,m) for(int i=n;i<m;i++)
 19 #define mfor(i,n,m) for(int i=n;i>m;i--)
 20 #define nfor(i,n,m) for(int i=n;i>=m;i--)
 21 #define forn(i,n,m) for(int i=n;i<=m;i++)
 22 #define scadd(a,b) scanf("%d%d",&a,&b)
 23 #define memset0(a) memset(a,0,sizeof(a))
 24 #define scaddd(a,b,c) scanf("%d%d%d",&a,&b,&c)
 25 #define scadddd(a,b,c,d) scanf("%d%d%d%d",&a,&b,&c,&d)
 26 
 27 #define INF 0x3f3f3f3f
 28 #define maxn 100005
 29 typedef long long ll;
 30 using namespace std;
 31 //---------AC(^-^)AC---------\\
 32 
 33 deque<int>::iterator it;
 34 struct node
 35 {
 36     deque<int> q;
 37     int num[maxn];
 38 }block[405];
 39 int n, m, blo, ans;
 40 int pos[maxn];
 41 
 42 void update(int a, int b)
 43 {
 44     if (pos[a] == pos[b])
 45     {
 46         it = block[pos[b]].q.begin() + ((b-1)%blo);
 47         int tmp = *it;
 48         block[pos[b]].q.erase(block[pos[b]].q.begin() + ((b-1)%blo));
 49         block[pos[b]].q.insert(block[pos[a]].q.begin() + ((a-1)%blo), tmp);
 50     }
 51     else
 52     {
 53         it = block[pos[b]].q.begin() + ((b-1)%blo);
 54         int tmp = *it;
 55         block[pos[b]].num[tmp]--;
 56         block[pos[b]].q.erase(block[pos[b]].q.begin() + ((b-1)%blo));
 57         for (int i = pos[a]; i < pos[b]; i++) {
 58             int x = block[i].q.back();
 59             block[i].q.pop_back();
 60             block[i].num[x]--;
 61             block[i + 1].q.push_front(x);
 62             block[i + 1].num[x]++;
 63         }
 64         block[pos[a]].q.insert(block[pos[a]].q.begin() + ((a-1)%blo), tmp);
 65         block[pos[a]].num[tmp]++;
 66     }
 67 }
 68 void query(int a, int b, int c)
 69 {
 70     ans=0;
 71     if (pos[a] == pos[b])
 72     {
 73         for (it = block[pos[a]].q.begin() + ((a-1)%blo); it <= block[pos[a]].q.begin() + ((b-1)%blo); it++)
 74             if ((*it) == c) ans++;
 75     }
 76     else {
 77         for (int i = pos[a] + 1; i < pos[b]; i++)    ans += block[i].num[c];
 78         for (it = block[pos[a]].q.begin() + ((a-1)%blo); it < block[pos[a]].q.end(); it++)
 79             if ((*it) == c) ans++;
 80         for (it = block[pos[b]].q.begin(); it <= block[pos[b]].q.begin() + ((b-1)%blo); it++)
 81             if ((*it) == c) ans++;
 82     }
 83     printf("%d\n", ans);
 84 }
 85 
 86 int main()
 87 {
 88     scad(n);
 89     blo = sqrt(n);
 90     if (n%blo) blo++;
 91     forn(i, 1, n) pos[i] = (i - 1)/blo + 1;
 92 
 93     forn(i, 1, n) {
 94         int x;
 95         scad(x);
 96         int s = pos[i];
 97         block[s].q.push_back(x);
 98         block[s].num[x]++;
 99     }
100     scad(m);
101     ans = 0;
102     while (m--)
103     {
104         int op;
105         scad(op);
106         if (op == 1)
107         {
108             int l, r;
109             scadd(l, r);
110             l = (l + ans - 1) % n+1;
111             r = (r + ans - 1) % n+1;
112             if (l > r) swap(l, r);
113             update(l, r);
114         }
115         else
116         {
117             int l, r, k;
118             scaddd(l, r, k);
119             l = (l + ans - 1) % n + 1;
120             r = (r + ans - 1) % n + 1;
121             k = (k + ans - 1) % n + 1;
122             if (l > r) swap(l, r);
123             query(l, r, k);
124         }
125     }
126     return 0;
127 }

猜你喜欢

转载自www.cnblogs.com/mile-star/p/10484342.html
今日推荐