题目来源: CodeForces
基准时间限制:1.5 秒 空间限制:131072 KB 分值: 320

小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

分块 封装 队列

安利隔壁sdfzyhx的Splay解法: http://blog.csdn.net/sdfzyhx/article/details/73655923

这个循环操作看上去很麻烦,很难用数据结构直接维护。

考虑分块,每块内维护数列和每个数的出现次数,这样每次循环的时候只需要修改首尾两块。

查询时就暴力统计首尾两块,中间直接查桶即可。

为了防止循环过多导致块严重变形,每次循环的时候把每个中间整块的尾元素移到下一个整块里,这样每块的大小可以保持不变。

因为块内操作有点多,写成了封装形式的,看着异常舒心233

块内用循环队列好像比链表省空间?

(算错了数组大小,RE了三次)

 #include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
const int mxn=;
const int N=;
int read(){
int x=,f=;char ch=getchar();
while(ch<'' || ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>='' && ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
int n;
struct chain{
int a[],hd,tl;
int cnt[mxn];
void init(){hd=;tl=;return;}
void add_front(int x){
hd=hd-;if(hd<)hd=;
a[hd]=x;
cnt[x]++;
return;
}
void add_back(int x){
tl=tl+;if(tl>)tl=;
a[tl]=x;
cnt[x]++;
return;
}
void del_front(){
cnt[a[hd]]--;
hd=hd+;if(hd>)hd=;
return;
}
void del_back(){
cnt[a[tl]]--;
tl=tl-;if(tl<)tl=;
return;
}
void rotate(int l,int r){
// printf("rotate:%d %d\n",l,r);
int st=(hd+l-)%,ed=(hd+r-)%;
// printf("st:%d ed:%d\n",st,ed);
int tmp=a[ed];
while(ed!=st){
a[ed]=(ed==)?a[]:a[ed-];
ed--;if(ed<)ed=;
}
a[st]=tmp;
return;
}
int calc(int L,int R,int K){
int st=(hd+L-)%,ed=(hd+R-)%;
int res=(a[st]==K);
while(st^ed){
st=st+;if(st>)st=;
res+=(a[st]==K);
}
return res;
}
int calc_back(int n,int K){
// printf("cback:n:%d K:%d\n",n,K);
int st=tl-n+;
// printf("st:%d tl:%d\n",st,tl);
if(st<)st+=;
int res=(a[st]==K);
while(st^tl){
st=st+;if(st>)st=;
if(a[st]==K)res++;
}
return res;
}
int calc_front(int n,int K){
int ed=(hd+n-)%;
int st=hd;
int res=(a[st]==K);
while(st^ed){
st=st+;if(st>)st=;
if(a[st]==K)res++;
}
return res;
}
int head(){
return a[hd];
}
int tail(){
return a[tl];
}
void debug(){
printf("debug:\n");
int x=hd;
printf("%d ",a[hd]);
while(x^tl){
x++;if(x>)x=;
printf("%d ",a[x]);
}
puts("");
return;
}
}c[N];
int a[mxn];
int L[N],R[N],sz,block=;
int bl[mxn];
int lastans=;
void solve(){
int Q=read(),op,ql,qr;
while(Q--){
// printf("Q:%d\n",Q);
op=read();
ql=read();ql=(ql+lastans-)%n+;
qr=read();qr=(qr+lastans-)%n+;
if(ql>qr)swap(ql,qr);
if(op==){
if(bl[ql]==bl[qr]){
c[bl[ql]].rotate(ql-L[bl[ql]]+,qr-L[bl[ql]]+);
}
else{
for(int i=bl[ql]+;i<bl[qr];i++){
c[i].add_front(c[i-].tail());
c[i-].del_back();
}
c[bl[qr]].add_front(c[bl[qr]-].tail());
c[bl[qr]-].del_back();
//
c[bl[qr]].rotate(,qr-L[bl[qr]]++);
c[bl[ql]].add_back(c[bl[qr]].head());
//把最后一个元素转到最前面,再加到最前一块的末尾
c[bl[qr]].del_front();
c[bl[ql]].rotate(ql-L[bl[ql]]+,R[bl[ql]]-L[bl[ql]]+);
}
}
else{
int K=read();K=(K+lastans-)%n+;
if(bl[ql]==bl[qr]){
int res=;
res=c[bl[ql]].calc(ql-L[bl[ql]]+,qr-L[bl[ql]]+,K);
printf("%d\n",res);
lastans=res;
continue;
}
int res=;
for(int i=bl[ql]+;i<bl[qr];i++){
res+=c[i].cnt[K];
}
// c[bl[ql]].debug();
// c[bl[qr]].debug();
res+=c[bl[ql]].calc_back(R[bl[ql]]-ql+,K);
res+=c[bl[qr]].calc_front(qr-L[bl[qr]]+,K);
printf("%d\n",res);
lastans=res;
}
}
return;
}
int main(){
int i,j;
n=read();
for(i=;i<=n;i++)a[i]=read();
// block=min(n,(int)sqrt(n+0.5)+123);
block=;
sz=(n-)/block+;
for(i=;i<=sz;i++){
L[i]=R[i-]+;
R[i]=block*i;
c[i].init();
}
R[sz]=min(R[sz],n);
for(i=;i<=sz;i++){
for(j=L[i];j<=R[i];j++){
c[i].add_back(a[j]);
bl[j]=i;
}
}
solve();
return ;
}

51nod1471 小S的兴趣的更多相关文章

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

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

  2. 51nod 1471 小S的兴趣 sqrt

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

  3. Java桌球小游戏(兴趣制作)

    两张图片放在src的同级目录下 版本一.出现窗口package cn.xjion.game;/** * 出现窗口 * @author xjion * */import java.awt.*;impor ...

  4. 对于前端,「微信小程序」其实不美好

    微信小程序开放公测了,9月底我曾经写过一篇 「微信小程序」来了,其中最后一句:"谢天谢地,我居然还是个前端". 这种火爆的新事物总是令人激动,感谢这个时代. 但是,当我真作为开发者 ...

  5. 迅雷首席架构师刘智聪:微信小程序的架构与系统设计的几点观感

    笔者注:本文来自于迅雷首席工程师刘智聪的个人分享,他毕业于南昌大学化学系,加入迅雷后设计开发了多款迅雷核心产品,凭借“大规模网络流媒体服务关键支撑技术”项目获得2015年国家科学技术进步奖二等奖,同时 ...

  6. 微信小程序各类型的自定义组件篇

    由于本人最近在开发小程序项目,期间对小程序有花点时间去研究,同时也找了网上大牛的一些案例,在这里分享部分自定义组件,部分代码是copy大牛案例的,有对小程序有兴趣的伙伴拿走,不谢! 源码下载地址:ht ...

  7. wn-cli 像React组件开发一样来开发微信小程序

    项目地址:wn-cli wn-cli wn-cli 像React组件开发一样来开发微信小程序 名字由来:wn -> weapp native 取第一个字母 Install npm install ...

  8. 从“跳一跳”来看微信小程序的未来

    从“跳一跳”来看微信小程序的未来   相信大家这两天都被微信新推出的小程序跳一跳刷爆了朋友圈,为了方便用户在使用过程中切换小程序,微信在这次6.6.1版本中加入了下拉可快速切换小程序的功能,而“跳一跳 ...

  9. 微信小程序报错,不在以下 request 合法域名列表中(引起的探索)

       最近因为突然对小程序有兴趣,然后开始了自学之旅.     在学习的过程当中遇到了一个问题,控制台报错,提示:不在以下 request 合法域名列表中,如下图所示 然后我就开始了搜索之旅,相对觉得 ...

随机推荐

  1. linux桌面使用鼠标中间健粘帖

    使用linux桌面很久了,一直习惯鼠标左键选中,右健弹出菜单复制粘帖. 没想到linux使用鼠标中间健粘帖,很方便. 参考:Linux鼠标中键复制粘贴之谜[Felix蛋疼科普贴] 用鼠标左键单击待复制 ...

  2. Hibernate(八)

    三套查询之Criteria查询 完全面向对象的,不需要写任可查询语句. 1.查询所有的学生 //1.查询所有的学生 @Test public void test1(){ Criteria criter ...

  3. iOS界面设计之基础控件的学习 --- UITextField

    学习iOS界面设计也有段时间了,每次写到一些基础控件(如:UILable . UITextField)的时候就深觉应该总结一个函数来实现这些基础控件的属性设置,所以下面就是我对UITextField的 ...

  4. Qt多线程-总结QThread-QThreadPool-QtConcurrent

    版权声明:若无来源注明,Techie亮博客文章均为原创. 转载请以链接形式标明本文标题和地址: 本文标题:Qt多线程-总结QThread-QThreadPool-QtConcurrent     本文 ...

  5. PAT L1-015 跟奥巴马一起画方块

    https://pintia.cn/problem-sets/994805046380707840/problems/994805124398956544 美国总统奥巴马不仅呼吁所有人都学习编程,甚至 ...

  6. 解决pciss_spc导入提示表空间不存在以及扩展失败的问题

    select NAME FROM USER$ ORDER BY NAME ; CREATE USER pciss IDENTIFIED BY pciss ; GRANT DBA TO pciss ; ...

  7. LoadRunner函数大全之中文解释

    LoadRunner函数大全之中文解释

  8. Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction

    我在update数据库的时候出现的死锁 数据库表死锁 Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackExcept ...

  9. js中如何获取页面的Url,域名和端口号

    有时候通过获取上个页面的Url来做一个跳转,获取域名防止非正常访问 获取上一个页面的一个URL,这个URL一般做一个页面的跳转 window.location.href <script>w ...

  10. DBGRID控件里可以实现SHIFT复选吗?怎么设置?

    //////////////////////////////////////////////////    功能概述:公用的列表框选择框,是用DBGrid网格////    注意事项:希望用Query ...