小S喜欢有趣的事。但是,每个人的兴趣都是独特的。小S热衷于自问自答。有一天,小S想出了一个问题。

有一个包含n个正整数的数组a和针对这个数组的几个问题。这些问题有两种类型:

1.      在数组下标l到r的部分上,将一个单元格循环移动到右端。即以下面方式重新分配数组上的元素。

a[l], a[l+1], ..., a[r-1], a[r] → a[r], a[l], a[l+1], ..., a[r-1].

2.      在数组下标l到r的部分上,计算有多少元素的值与k相等。

小S很喜欢这个问题并且很快解决了它,你是否能够解决它呢?

分块,每一个块维护一个链表,也可以用数组模拟,不包含整个区间就暴力更改。

O(nsqrt(n))

右移相当于在末尾删除一个元素,在首部添加一个元素。

debug了很久,原因:在解密l,r,k,后,有可能l > r,这个时候要swap(l,r)

代码:

  //File Name: nod1471.cpp
//Author: long
//Mail: 736726758@qq.com
//Created Time: 2016年09月15日 星期四 21时17分30秒 #include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>
#include <map>
#define LL long long
using namespace std;
const int MAXN = + ;
const int NUM = ;
int l[MAXN/NUM+],r[MAXN/NUM+],belong[MAXN];
int a[MAXN],tmp[NUM],cnt;
struct Block{
int b[NUM],s[MAXN],head,tot;
void build(const int l,const int r){
tot = head = ;
memset(s,,sizeof s);
for(int i=l;i<=r;i++){
b[tot++] = a[i];
s[a[i]]++;
}
}
void right(int st){
head--;
if(head < ) head = tot - ;
cnt = b[head];
s[cnt]--;
b[head] = st;
s[st]++;
}
void reset(){
if(head == ) return ;
for(int i=;i<tot;i++) tmp[i] = b[i];
int u = ;
for(int i=head;i<tot;i++) b[u++] = tmp[i];
for(int i=;i<head;i++) b[u++] = tmp[i];
head = ;
}
void brute(int st,int l,int r){
reset();
cnt = b[r];
s[cnt]--;
for(int i=r;i>l;i--) b[i] = b[i-];
b[l] = st;
s[st]++;
}
int get(int k){
k = (head + k) % tot;
return b[k];
}
int query(int k){
return s[k];
}
int cal(int l,int r,int k){
reset();
int res = ;
for(int i=l;i<=r;i++)
if(b[i] == k) res++;
return res;
}
}block[MAXN / NUM + ];
void solve(int n){
for(int i=;i<=n;i++)
belong[i] = (i - ) / NUM;
int tot = belong[n] + ,u=;
for(int i=;i<tot;i++,u+=NUM){
l[i] = u;
r[i] = min(u + NUM - ,n);
}
for(int i=;i<tot;i++)
block[i].build(l[i],r[i]);
int ans = ,q,op,x,y,k;
scanf("%d",&q);
while(q--){
scanf("%d %d %d",&op,&x,&y);
if(op == ){
x = (x + ans - ) % n + ;
y = (y + ans - ) % n + ;
if(x > y) swap(x,y);
int bx = belong[x],by = belong[y];
if(bx == by){
cnt = block[bx].get(y-l[bx]);
block[bx].brute(cnt,x-l[bx],y-l[bx]);
}
else{
cnt = block[by].get(y-l[by]);
block[bx].brute(cnt,x-l[bx],r[bx]-l[bx]);
for(int i=bx+;i<by;i++)
block[i].right(cnt);
block[by].brute(cnt,,y-l[by]);
}
}
else{
scanf("%d",&k);
x = (x + ans - ) % n + ;
y = (y + ans - ) % n + ;
k = (k + ans - ) % n + ;
if(x > y) swap(x,y);
//cout << x << " " << y << " " << k << " " << endl;
int bx = belong[x],by = belong[y];
ans = ;
if(bx == by)
ans = block[bx].cal(x-l[bx],y-l[bx],k);
else{
ans += block[bx].cal(x-l[bx],r[bx]-l[bx],k);
for(int i=bx+;i<by;i++)
ans += block[i].query(k);
ans += block[by].cal(,y-l[by],k);
}
printf("%d\n",ans);
}
}
}
int main(){
int n;
while(~scanf("%d",&n)){
for(int i=;i<=n;i++) scanf("%d",a + i);
solve(n);
}
return ;
}

51nod 1471 小S的兴趣 sqrt的更多相关文章

  1. 51nod 1471 小S的兴趣 | 分块 链表

    51nod 1471 小S的兴趣 题面 小S喜欢有趣的事.但是,每个人的兴趣都是独特的.小S热衷于自问自答.有一天,小S想出了一个问题. 有一个包含n个正整数的数组a和针对这个数组的几个问题.这些问题 ...

  2. 51nod1471 小S的兴趣

    题目来源: CodeForces 基准时间限制:1.5 秒 空间限制:131072 KB 分值: 320 小S喜欢有趣的事.但是,每个人的兴趣都是独特的.小S热衷于自问自答.有一天,小S想出了一个问题 ...

  3. 51nod 1631 小鲨鱼在51nod小学

    基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题 鲨鱼巨巨2.0(以下简称小鲨鱼)以优异的成绩考入了51nod小学.并依靠算法方面的特长,在班里担任了许多职务.   ...

  4. 51nod 2489 小b和灯泡

    小b有n个关闭的灯泡,编号为1...n. 小b会进行n轮操作,第i轮她会将编号为i的倍数的灯泡的开关状态取反,即开变成关,关变成开. 求n轮操作后,有多少灯泡是亮着的. 收起   输入 输入一个数字表 ...

  5. 51nod 1831 小C的游戏

    小C和小L是好朋友,她们在玩一个游戏. 一开始有一个大小为n的石子堆,小C先手. 每次可以对这个石子堆拿走一个或者把这个石子堆分成等量的几份并只取其中一份(不能不变或只剩下一个). 如果取走最后一个人 ...

  6. 51nod——2489 小b和灯泡(打表/平方数)

    这题打表去找因子的个数然后判奇偶也行.预处理O(n) 扫一遍判断O(n). ; i * i <= n; i++){ for(int j = i; i * j <= n; j++){ div ...

  7. 51nod 2486 小b和矩阵

    小b有一个m行n列的矩阵. 她会从(1,1)开始,顺时针螺旋访问该矩阵,每个元素恰好被访问一次. 请你按小b的访问顺序输出每个元素. 收起   输入 第一行输入两个数m和n,其中0<m,n≤50 ...

  8. 51nod 2485 小b重排字符串

    小b有一个字符串S,现在她希望重排列S,使得S中相邻字符不同. 请你判断小b是否可能成功. 样例解释:将"aab"重排为"aba"即可. 收起   输入 输入一 ...

  9. 51nod 1643 小Q的家庭作业

    题意: f(n) = sigma(gcd(i,n))  1 <= i <= n g(n) = sigma(f(d))    d | n n = x1 * x2 * ... * xm 其中 ...

随机推荐

  1. mysql 存储过程简介

    存储过程类似一个存储在数据库的一个数据库脚本.它类似一个方法,可以批量执行一些数据库的操作. 本文编写一个简单的存储过程来快速了解存储过程. 1.因为存储过程类似编程语言的方法,所以方法中可能会用到 ...

  2. 省常中模拟 day1

    第一题: 题目大意: 给出N个数的数列,如果相邻的两个数加起来是偶数,那么就可以把这两个数消掉,求最多能消掉多少数. 解题过程: 1.先自己手工模拟了几组数据,发现不管消除的顺序如何,最终剩下的是一定 ...

  3. mac 下安装jmeter

    1.http://jmeter.apache.org/download_jmeter.cgi 下载jmeter 2.解压包 3.进入解压目录/bin/ 4.sh jmeter

  4. JAVA 集合List、Map、Set

    Collection(接口) Set(接口) HashSet(类) … List(接口) ArrayList(类) Vector(类) LinkedList(类) … Map(接口) HashMap( ...

  5. css2----清除浮动

    为什么要清除浮动? 非IE下,当容器的高度为auto,容器有浮动元素,此时容器的高度不能自己伸长适应内容的高度,造成内容溢出乃至影响布局,即所谓的“浮动溢出”,为防此象,需要清除浮动. 如何清除浮动? ...

  6. RSA非对称加密

    先上RSA加密算法的一些简介(截图自轩辕老师的课件): 嗯--RSA就是这么一回事,于是有了如下题目: 1.In an RSA system, the public key of a given us ...

  7. js从后台无法取值问题

    前台代码 <script type="text/javascript"> $(function () { var chart; $(document).ready(fu ...

  8. java.net.BindException: address already in use <null>:xxxx

    linux下,tomcat突然关闭了,执行关闭(shutdown.sh)和启动(startup.sh)成功后,tomcat仍未运行,查看tomcat的catalina日志发现这样一个报错:java.n ...

  9. IOS7 SDK 几宗罪

    IOS7 app 默认是全屏模式,所以之前的程序窗口会上向移动到状态栏上面,所以在底边会有一条大白边 表格单元格,默认是白色背景,之前程序设置的透明效果,这里不在起作用,需要用下面的委托方法改变.- ...

  10. Python条件语句

    1.简介 多个条件判断,用elif语句. 如果判断需要多个条件需同时判断时,可以使用 or (或),表示两个条件有一个成立时判断条件成功: 使用 and (与)时,表示只有两个条件同时成立的情况下,判 ...