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. 使用MyBatis Generator 1.3.7自动生成代码

    MyBatis Generator是一款mybatis自动代码生成工具,可以通过配置后自动生成文件. MyBatis Generator有几种方法可以生成代码,下面是其中一种.  一.官网下载 MyB ...

  2. 洛谷 P1273 【有线电视网】

    题目描述 某收费有线电视网计划转播一场重要的足球比赛.他们的转播网和用户终端构成一棵树状结构,这棵树的根结点位于足球比赛的现场,树叶为各个用户终端,其他中转站为该树的内部节点. 从转播站到转播站以及从 ...

  3. 廖雪峰JavaScript学习笔记(基础及数据类型、变量)

    先睹为快 alert('我要学JavaScript!'); Run: 基本语法: 1.每个语句以;结束,不强制 2.语句块用{...} 3.//单行注释,/*...*/ 多行注释 数据类型: 1.不区 ...

  4. Linux - 7种运行级别

    目录:etc/rc.d/init.d 1. linux开机过程 2. 运行级别(0-6) 存储位置 etc/inittab,开机加载,也可以用命令init [数字]切换. # 0 - 停机(默认时为0 ...

  5. Lua 语言基本语法

    第一个 Lua 程序 .交互式编程 Lua 提供了交互式编程模式.我们可以在命令行中输入程序并立即查看效果. Lua 交互式编程模式可以通过命令 lua -i 或 lua 来启用 .脚本式编程 我们可 ...

  6. Centos 7 搭建FTP详细配置步骤方法

    vsftpd的安裝使用: ftp概述:FTP(File Transfer protocol,文件传输协议)是经典的C/S架构的应用层协议,需要有服务端软件,客户端软件两个部共同组成实现文件传输功能. ...

  7. ELK安装使用教程

    一.说明 ELK是当下流行的日志监控系统.ELK是Elasticsearch.Logstash.Kibana三个软件的统称. 在ELK日志监控系统中,Logstash负责读取和结构化各类日志+发送给E ...

  8. windows下《Go Web编程》之Go环境配置和安装

    <Go Web编程>笔者是基于unix下讲述的,作为入门练手,我选择在windows下开发,全程按照目录进行... 一.安装 windows下需要安装MinGW,通过MinGW安装gcc支 ...

  9. mysql数据库基础语句训练题

    ; -- ---------------------------- -- Table structure for course -- ---------------------------- DROP ...

  10. js splice函数 数组增加,替换,删除

    splice函数参数介绍: 第一个参数: 对于数数组的操作起始位置. 第二个参数: 从第一个参数开始,删除数组中的个数. 从第三个参数之后所有参数(如果有):执行完第二步之后,都插入到第一个参数的起始 ...