51nod 1471 小S的兴趣

题面

小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很喜欢这个问题并且很快解决了它,你是否能够解决它呢?

Input

第一行包含整数 n (1 ≤ n ≤ 10*5) —数组元素的数量。第二行包含 n 个整数a[1], a[2], ..., a[n] (1 ≤ a[i] ≤ n)。

第三行包含唯一的整数 q (1 ≤ q ≤ 10*5) —问题的数量。接下来的q行包含了这些询问。

因为你需要在线回答这些问题,所以这些问题将会被编码。第一种类型的询问将会以以下形式给出: 1 Li Ri 。第二种类型的询问将会以以下形式给出: 2 Li Ri Ki 。所有输入的数字都是整数,它们满足以下条件:1 ≤ Li,Ri,Ki ≤ n.

为解码输入的问题,你需要按以下转换操作:

li = ((Li + lastans - 1) mod n) + 1;

ri = ((Ri + lastans - 1) mod n) + 1;

ki=((Ki + lastans - 1) mod n) + 1.

lastans 是到当前询问为止最后一个第二种类型的询问的答案 (初始, lastans = 0)。如果转换后, li 比 ri 大,你需要交换这两个数字。

Output

对于每一个第二种类型的问题以单独一行输出答案。

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

题解

这道题可以用分块做!(其实我就是想练习分块才来写的这道题……)

大约\(\sqrt n\)(因为担心空间爆炸,我取的是400个一块)分成一块,每块内部是一个链表。对于每一块,记录某数在其中出现的次数。

当进行修改的时候,把右端点上的元素拿下来,插到左端点前面即可。但是单纯这样做,可能会导致有的块变大、有的块变小,不利于时间复杂度的稳定,于是把区间中间的每一块最右边的元素拿下来,插到下一个块的左端点前面,这样每次修改时块的大小不会改变。

注意可能出现修改区间的 l, r 相等的情况——对于我的代码,这里不特判的话链表操作就会GG……

#include <cstdio>
#include <cstring>
#include <algorithm>
#define INF 0x3f3f3f3f
#define space putchar(' ')
#define enter putchar('\n')
using namespace std;
typedef long long ll;
template <class T>
bool read(T &x){
char c;
bool op = 0;
while(c = getchar(), c < '0' || c > '9')
if(c == '-') op = 1;
else if(c == EOF) return 0;
x = c - '0';
while(c = getchar(), c >= '0' && c <= '9')
x = x * 10 + c - '0';
if(op) x = -x;
return 1;
}
template <class T>
void write(T x){
if(x < 0) putchar('-'), x = -x;
if(x >= 10) write(x / 10);
putchar('0' + x % 10);
} const int M = 400, N = 1e5+400;
int n, q, a[N];
int st[N/M], ed[N/M], pre[N], nxt[N];
int blk[N], beg[N];
// 使用链表存储每一块内部信息
// blk是原来某一编号的元素的所在的位置
int cnt[N/M][N], ans; // 记录每一块内每个数有多少 void erase(int x){ //删除元素x
pre[nxt[x]] = pre[x];
nxt[pre[x]] = nxt[x];
cnt[blk[x]][a[x]]--;
}
void insert(int x, int y){ //在x前面插入y(同一块)
pre[y] = pre[x];
nxt[y] = x;
nxt[pre[x]] = y;
pre[x] = y;
blk[y] = blk[x];
cnt[blk[y]][a[y]]++;
}
int find(int x){ //找到第x个元素
int b = 1;
while(b < blk[n] && beg[b + 1] <= x) b++;
int ret = nxt[st[b]], pos = beg[b];
while(pos < x) pos++, ret = nxt[ret];
return ret;
}
void change(int l, int r){
int left = find(l), right = find(r);
int b1 = blk[left], b2 = blk[right];
erase(right);
insert(left, right);
for(int b = b1; b < b2; b++){
int x = pre[ed[b]];
erase(x);
insert(nxt[st[b + 1]], x);
}
}
int query(int l, int r, int x){
int left = find(l), right = find(r);
int b1 = blk[left], b2 = blk[right];
int ret = 0;
if(b1 == b2){
for(int i = left; i != nxt[right]; i = nxt[i])
if(a[i] == x) ret++;
return ret;
}
for(int pos = beg[b1 + 1] - 1, i = pre[ed[b1]]; pos >= l; pos--, i = pre[i])
if(a[i] == x) ret++;
for(int pos = beg[b2], i = nxt[st[b2]]; pos <= r; pos++, i = nxt[i])
if(a[i] == x) ret++;
for(int b = b1 + 1; b < b2; b++)
ret += cnt[b][x];
return ret;
}
int main(){
read(n);
for(int i = 1; i <= n; i++){
read(a[i]);
pre[i] = i - 1, nxt[i] = i + 1, blk[i] = (i - 1) / M + 1;
if(i % M == 1)
beg[blk[i]] = i, st[blk[i]] = n + blk[i], pre[i] = st[blk[i]], nxt[st[blk[i]]] = i;
if(i % M == 0 || i == n)
ed[blk[i]] = n + blk[i], nxt[i] = ed[blk[i]], pre[ed[blk[i]]] = i;
cnt[blk[i]][a[i]]++;
}
beg[blk[n] + 1] = n + 1;
read(q);
while(q--){
int op, l, r, x;
read(op), read(l), read(r);
l = (l + ans - 1) % n + 1;
r = (r + ans - 1) % n + 1;
if(l > r) swap(l, r);
if(op == 1 && l != r)
change(l, r);
else if(op == 2){
read(x);
x = (x + ans - 1) % n + 1;
write(ans = query(l, r, x)), enter;
}
}
return 0;
}

51nod 1471 小S的兴趣 | 分块 链表的更多相关文章

  1. 51nod 1471 小S的兴趣 sqrt

    小S喜欢有趣的事.但是,每个人的兴趣都是独特的.小S热衷于自问自答.有一天,小S想出了一个问题. 有一个包含n个正整数的数组a和针对这个数组的几个问题.这些问题有两种类型: 1.      在数组下标 ...

  2. 51nod1471 小S的兴趣

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

  3. 【CF896E】Welcome home, Chtholly 暴力+分块+链表

    [CF896E]Welcome home, Chtholly 题意:一个长度为n的序列ai,让你支持两种操作: 1.l r x:将[l,r]中ai>x的ai都减去x.2.l r x:询问[l,r ...

  4. bzoj 3781: 小B的询问 分块

    3781: 小B的询问 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 196  Solved: 135[Submit][Status] Descrip ...

  5. 51nod 1589 移数博弈【桶排序+链表】

    1589 移数博弈 基准时间限制:1 秒 空间限制:262144 KB 分值: 80 难度:5级算法题   小A和小B在玩一个游戏. 他们拥有一个数列. 小A在该数列中选择出最大的那个数,然后移出该数 ...

  6. 【BZOJ4548】小奇的糖果 set(链表)+树状数组

    [BZOJ4548]小奇的糖果 Description 有 N 个彩色糖果在平面上.小奇想在平面上取一条水平的线段,并拾起它上方或下方的所有糖果.求出最多能够拾起多少糖果,使得获得的糖果并不包含所有的 ...

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

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

  8. Codeforces 455D 分块+链表

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

  9. AcWing 251. 小Z的袜子| 分块+莫队

    传送门 题目描述 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿. 终于有一天,小Z再也无法忍受这恼人的找袜子过程,于是他决定听天由命. 具体来说,小Z把这N只袜子从 ...

随机推荐

  1. Python基础系列讲解——继承派生和组合的概念剖析

    Python作为一门面向对象的语言,它的面向对象体系中主要存在这么两种关系,一个是“类”和“实例”的关系,另一个是“父类”和“子类”的关系. 所谓“类”是从一堆对象中以抽象的方式把相同的特征归类得到的 ...

  2. Hadoop错误码速查

    经常遇到的exception是:PipeMapRed.waitOutputThreads(): subprocess failed with code N "OS error code 1: ...

  3. 安装配置php

    安装PHP       1.安装PHP       yum install php   #根据提示输入Y直到安装完成        2.安装PHP组件,使PHP支持 MySQL.PHP支持FastCG ...

  4. fetch err : "Body not allowed for GET or HEAD requests"

    在使用 fetch 的时候 报了  "Body not allowed for GET or HEAD requests" 这个错. 代码如下: 一番google , 找到答案了. ...

  5. comet4j推送 405/500 JSON转换异常

    因为Comet4J工作在NIO方式下,所以我们需要调整服务器连接器配置,更换为NOI连接器. 打开server.xml文件将找到原先的连接器配置: <Connector executor=&qu ...

  6. JavaWeb项目通过调用cmd实现备份数据库的功能

    1.别急着上车,先测试一下能否成功调用cmd,可以尝试通过cmd命令打开计算器,代码如下:     2.能成功打开计算器后,证明调用cmd的方法是没错的,现在把cmd命令字符串改成我们备份数据库的 命 ...

  7. jdbc连接获取表名称

    1,Class.forName可以替换为mysql之类其他的数据库驱动 public Connection connect(String url,String username,String pw, ...

  8. Scrum Meeting 10.25

    成员 已完成任务 下一阶段任务 用时 徐越 阅读前端代码中和通信相关的部分 学习服务器配置 4h 赵庶宏 阅读前端代码中和通信相关的部分 学习服务器配置 4h 薄霖 继续做UI开发 界面优化 4h 武 ...

  9. 学习pl/sql之一

    --使用pl/sql语句打印一个hello world begin   dbms_output.put_line('hello,world'); end;      但是在sqlplus里面就不一样了 ...

  10. 手机访问本地php项目遇到的问题及解决

    做html5的本地应用要调试后台,学了下php 按照和连j2ee的时候一样,电脑发射wifi,ipconfig..等等  发现tomcat的可以访问,apache的不能访问,搜索好久,没找到解答, j ...