51nod1471 小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很喜欢这个问题并且很快解决了它,你是否能够解决它呢?
第一行包含整数 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 大,你需要交换这两个数字。
对于每一个第二种类型的问题以单独一行输出答案。
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
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的兴趣的更多相关文章
- 51nod 1471 小S的兴趣 | 分块 链表
51nod 1471 小S的兴趣 题面 小S喜欢有趣的事.但是,每个人的兴趣都是独特的.小S热衷于自问自答.有一天,小S想出了一个问题. 有一个包含n个正整数的数组a和针对这个数组的几个问题.这些问题 ...
- 51nod 1471 小S的兴趣 sqrt
小S喜欢有趣的事.但是,每个人的兴趣都是独特的.小S热衷于自问自答.有一天,小S想出了一个问题. 有一个包含n个正整数的数组a和针对这个数组的几个问题.这些问题有两种类型: 1. 在数组下标 ...
- Java桌球小游戏(兴趣制作)
两张图片放在src的同级目录下 版本一.出现窗口package cn.xjion.game;/** * 出现窗口 * @author xjion * */import java.awt.*;impor ...
- 对于前端,「微信小程序」其实不美好
微信小程序开放公测了,9月底我曾经写过一篇 「微信小程序」来了,其中最后一句:"谢天谢地,我居然还是个前端". 这种火爆的新事物总是令人激动,感谢这个时代. 但是,当我真作为开发者 ...
- 迅雷首席架构师刘智聪:微信小程序的架构与系统设计的几点观感
笔者注:本文来自于迅雷首席工程师刘智聪的个人分享,他毕业于南昌大学化学系,加入迅雷后设计开发了多款迅雷核心产品,凭借“大规模网络流媒体服务关键支撑技术”项目获得2015年国家科学技术进步奖二等奖,同时 ...
- 微信小程序各类型的自定义组件篇
由于本人最近在开发小程序项目,期间对小程序有花点时间去研究,同时也找了网上大牛的一些案例,在这里分享部分自定义组件,部分代码是copy大牛案例的,有对小程序有兴趣的伙伴拿走,不谢! 源码下载地址:ht ...
- wn-cli 像React组件开发一样来开发微信小程序
项目地址:wn-cli wn-cli wn-cli 像React组件开发一样来开发微信小程序 名字由来:wn -> weapp native 取第一个字母 Install npm install ...
- 从“跳一跳”来看微信小程序的未来
从“跳一跳”来看微信小程序的未来 相信大家这两天都被微信新推出的小程序跳一跳刷爆了朋友圈,为了方便用户在使用过程中切换小程序,微信在这次6.6.1版本中加入了下拉可快速切换小程序的功能,而“跳一跳 ...
- 微信小程序报错,不在以下 request 合法域名列表中(引起的探索)
最近因为突然对小程序有兴趣,然后开始了自学之旅. 在学习的过程当中遇到了一个问题,控制台报错,提示:不在以下 request 合法域名列表中,如下图所示 然后我就开始了搜索之旅,相对觉得 ...
随机推荐
- 201621123037 《Java程序设计》第8周学习总结
作业08-集合 1. 本周学习总结 以你喜欢的方式(思维导图或其他)归纳总结集合相关内容. 答: 思维导图: 其他-笔记: 2. 书面作业 1. ArrayList代码分析 1.1 解释ArrayLi ...
- IDEA换行CRLF, LF, CR的解释和默认设置
在window下开发有一个大坑,就是换行默认是CRLF,也就是回车换行,但是Linux下只有换行LF,这样代码提交后,会出现编译问题,所以最好的办法是在IDEA下设置默认为LF. 首先我们先介绍CRL ...
- python/django将mysql查询结果转换为字典组
使用python查询mysql数据库的时候,默认查询结果没有返回表字段名称,不方便使用.为了方便使用一般会选择将查询结果加上字段名称以字典组的方式返回查询结果. 实现如下: def dict_fetc ...
- java 基础 --File
1, 创建文件 File file = new File(path); file.createNewFile(); //如果路径不存在,会抛异常 file.mkdir();//如果路径不存在,返回fa ...
- APDU命令与响应格式【转】
本文转载自:http://map.im/apduintroduce 命令格式 APDU命令由命令头和命令体组成: CLA | INS | P1 | P2 | Lc | DATA | Le命令头: CL ...
- 【bzoj4244】邮戳拉力赛 背包dp
题目描述 IOI铁路是由N+2个站点构成的直线线路.这条线路的车站从某一端的车站开始顺次标号为0...N+1. 这条路线上行驶的电车分为上行电车和下行电车两种,上行电车沿编号增大方向行驶,下行电车沿编 ...
- 【bzoj2656】[Zjoi2012]数列(sequence) 高精度
题目描述 给出数列 $A$ 的递推公式如下图所示,$T$ 次给定 $n$ ,求 $A_n$ . 输入 输入文件第一行有且只有一个正整数T,表示测试数据的组数.第2-T+1行,每行一个非负整数N. 输出 ...
- BZOJ3884 上帝与集合的正确用法(欧拉函数)
设f(n)为模n时的答案,由2k mod n=2k mod φ(n)+φ(n) mod n(并不会证),且k mod φ(n)=f(φ(n)),直接就可以得到一个递推式子.记搜一发即可. #inclu ...
- [HNOI2014]江南乐 博弈论
题面 题面 题解 首先我们知道一个关于除法的重要性质:对于一个固定的\(i\),表达式\(\frac{i}{m}\)的取值只有根号个. 因此我们考虑如何优化SG函数的求解. 观察到在取值相同的同一段中 ...
- [POI2012]OKR-A Horrible Poem hash
题面:洛谷 题解: 首先我们需要知道一个性质,串s的最小循环节 = len - next[len].其中next[len]表示串s的一个最长长度使得s[1] ~ s[next[len]] == s[l ...