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:
- 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?
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:
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.
OutputFor each query of the 2-nd type print the answer on a single line.
Examples7
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
分块+双端队列
每次更新对每块进行操作:
1.中间的整块:取出最后一个放入下一块的前端;
2.两端的块:左边的块放入给定右边界位置的数字,右端的块删除给定右边界位置的数字
每次询问:
中间的整块直接查询,两边的块遍历可访问的位置;
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }