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.两端的块:左边的块放入给定右边界位置的数字,右端的块删除给定右边界位置的数字
每次询问:
中间的整块直接查询,两边的块遍历可访问的位置;
 #include <cstdio>
#include <stack>
#include <cmath>
#include <queue>
#include <string>
#include <queue>
#include <cstring>
#include <iostream>
#include <algorithm> #define lid id<<1
#define rid id<<1|1
#define closein cin.tie(0)
#define scac(a) scanf("%c",&a)
#define scad(a) scanf("%d",&a)
#define print(a) printf("%d\n",a)
#define debug printf("hello world")
#define form(i,n,m) for(int i=n;i<m;i++)
#define mfor(i,n,m) for(int i=n;i>m;i--)
#define nfor(i,n,m) for(int i=n;i>=m;i--)
#define forn(i,n,m) for(int i=n;i<=m;i++)
#define scadd(a,b) scanf("%d%d",&a,&b)
#define memset0(a) memset(a,0,sizeof(a))
#define scaddd(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define scadddd(a,b,c,d) scanf("%d%d%d%d",&a,&b,&c,&d) #define INF 0x3f3f3f3f
#define maxn 100005
typedef long long ll;
using namespace std;
//---------AC(^-^)AC---------\\ deque<int>::iterator it;
struct node
{
deque<int> q;
int num[maxn];
}block[];
int n, m, blo, ans;
int pos[maxn]; void update(int a, int b)
{
if (pos[a] == pos[b])
{
it = block[pos[b]].q.begin() + ((b-)%blo);
int tmp = *it;
block[pos[b]].q.erase(block[pos[b]].q.begin() + ((b-)%blo));
block[pos[b]].q.insert(block[pos[a]].q.begin() + ((a-)%blo), tmp);
}
else
{
it = block[pos[b]].q.begin() + ((b-)%blo);
int tmp = *it;
block[pos[b]].num[tmp]--;
block[pos[b]].q.erase(block[pos[b]].q.begin() + ((b-)%blo));
for (int i = pos[a]; i < pos[b]; i++) {
int x = block[i].q.back();
block[i].q.pop_back();
block[i].num[x]--;
block[i + ].q.push_front(x);
block[i + ].num[x]++;
}
block[pos[a]].q.insert(block[pos[a]].q.begin() + ((a-)%blo), tmp);
block[pos[a]].num[tmp]++;
}
}
void query(int a, int b, int c)
{
ans=;
if (pos[a] == pos[b])
{
for (it = block[pos[a]].q.begin() + ((a-)%blo); it <= block[pos[a]].q.begin() + ((b-)%blo); it++)
if ((*it) == c) ans++;
}
else {
for (int i = pos[a] + ; i < pos[b]; i++) ans += block[i].num[c];
for (it = block[pos[a]].q.begin() + ((a-)%blo); it < block[pos[a]].q.end(); it++)
if ((*it) == c) ans++;
for (it = block[pos[b]].q.begin(); it <= block[pos[b]].q.begin() + ((b-)%blo); it++)
if ((*it) == c) ans++;
}
printf("%d\n", ans);
} int main()
{
scad(n);
blo = sqrt(n);
if (n%blo) blo++;
forn(i, , n) pos[i] = (i - )/blo + ; forn(i, , n) {
int x;
scad(x);
int s = pos[i];
block[s].q.push_back(x);
block[s].num[x]++;
}
scad(m);
ans = ;
while (m--)
{
int op;
scad(op);
if (op == )
{
int l, r;
scadd(l, r);
l = (l + ans - ) % n+;
r = (r + ans - ) % n+;
if (l > r) swap(l, r);
update(l, r);
}
else
{
int l, r, k;
scaddd(l, r, k);
l = (l + ans - ) % n + ;
r = (r + ans - ) % n + ;
k = (k + ans - ) % n + ;
if (l > r) swap(l, r);
query(l, r, k);
}
}
return ;
}

CodeForces - 455D的更多相关文章

  1. CodeForces 455D 分块

    题目链接:http://codeforces.com/problemset/problem/455/D 题意:给定一个长度为n的序列a[]. m次操作.共有两种操作 1 l r:将序列的a[l].a[ ...

  2. Serega and Fun Codeforces - 455D || queue

    https://codeforces.com/problemset/problem/455/D 其实方法很多,然而当初一个也想不到... 1.分块,块内用链表维护 修改[l,r]就当成删除第r个元素, ...

  3. Serega and Fun CodeForces - 455D (分块 或 splay)

    大意:给定n元素序列, 2种操作 将区间$[l,r]$循环右移1位 询问$[l,r]$中有多少个等于k的元素 现在给定q个操作, 输出操作2的询问结果, 强制在线 思路1: 分块 每个块内维护一个链表 ...

  4. Codeforces 455D 分块+链表

    题意: 给定一个长度为 N 的序列两种操作1 l r 将[l,r]的数向右循环移位 2 l r 询问[l,r]内有多少个数等于 k其中 N,Q≤105,ai≤N 强制在线 思路: 1. 每块用一个链表 ...

  5. python爬虫学习(5) —— 扒一下codeforces题面

    上一次我们拿学校的URP做了个小小的demo.... 其实我们还可以把每个学生的证件照爬下来做成一个证件照校花校草评比 另外也可以写一个物理实验自动选课... 但是出于多种原因,,还是绕开这些敏感话题 ...

  6. 【Codeforces 738D】Sea Battle(贪心)

    http://codeforces.com/contest/738/problem/D Galya is playing one-dimensional Sea Battle on a 1 × n g ...

  7. 【Codeforces 738C】Road to Cinema

    http://codeforces.com/contest/738/problem/C Vasya is currently at a car rental service, and he wants ...

  8. 【Codeforces 738A】Interview with Oleg

    http://codeforces.com/contest/738/problem/A Polycarp has interviewed Oleg and has written the interv ...

  9. CodeForces - 662A Gambling Nim

    http://codeforces.com/problemset/problem/662/A 题目大意: 给定n(n <= 500000)张卡片,每张卡片的两个面都写有数字,每个面都有0.5的概 ...

随机推荐

  1. java的一些基本概念——java11、jdk、jre、jvm等

    Java字节码 先介绍下c语言的编译过程,写好代码用编译器(比如gcc)编译过后是机器能够直接执行的二进制机器码. java也类似这种情况,但是java代码文件编译过后不是任何机器都能识别的机器码,而 ...

  2. (转载)【UGUI】侧面滑出的菜单栏,宽度自适应

    首先看下项目效果 实现效果 发现实现效果并不难,利用动画(iTween)+UGUI 有一个长按的判断处理即可 附上项目和代码 using System.Collections; using Syste ...

  3. null与undefined的区别

    null和undefined是JavaScript五种基本数据类型中的两种. null是一个特殊值,但我们常常误解它,有时候我们会把它和另一个数据类型undefined的含义互相混淆. 首先我们来了解 ...

  4. js Array​.prototype​.reduce()

    例子: , , , ]; const reducer = (accumulator, currentValue) => accumulator + currentValue; // 1 + 2 ...

  5. chrome 调试功能使用说明

    单文件搜索 ctrl+f 全局搜索 ctrl+shift+f

  6. [python]PyPI使用国内源

    PyPI使用国内源 对于默认的pip源的速度太慢,一些国内的pip源,如下: 豆瓣(douban) https://pypi.douban.com/simple 阿里云 http://mirrors. ...

  7. vue query或params传参

    1.query 传递端: this.$router.push({ path:"/AccountFP", query:{ id:row.id, userId:row.userId } ...

  8. OPENAPI规范Swagger

    OPENAPI规范 是一种规范,Swagger是一种工具,Swagger帮我们使用OPENAPI更具体更完善,更好. 博客1:https://app.swaggerhub.com/help/index ...

  9. jRazor

    引擎渲染速度竞赛 条数据 × 次渲染测试 建议在高版本的浏览器上进行测试,避免浏览器停止响应 测试环境: 开始测试»  

  10. vue render里面的nativeOn

    vue render里面的nativeOn的解释官方的解释是:// 仅对于组件,用于监听原生事件,而不是组件内部使用 `vm.$emit` 触发的事件. 官方的解释比较抽象 个人理解: 父组件要在子组 ...