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 合法域名列表中,如下图所示 然后我就开始了搜索之旅,相对觉得 ...
随机推荐
- OSG学习:用多通道(multiple passes)实现透明度
osgFX库提供了一个用于多通道渲染(multi-pass rendering)的框架.每个你想要渲染的子图都应该被添加到osgFX::Effect节点,多通道技术的定义和使用都可以在这个节点中完成. ...
- 【第三周】【】cppunit!
coding.net地址:https://coding.net/u/Boxer_ ssh:git@git.coding.net:Boxer_/homework.git https://coding.n ...
- 转 Maven常用仓库地址以及手动添加jar包到仓库
转自:http://blog.csdn.net/kqygww/article/details/12837783 共有的仓库 http://repository.sonatype.org/content ...
- KMP算法模板(pascal)
洛谷P3375: program rrr(input,output); var i,j,lena,lenb:longint; a,b:ansistring; next:..]of longint; b ...
- TCP(Transmission Control Protocol)学习笔记
一.TCP(Transmission Control Protocol)原理介绍(参考维基百科) TCP连接包括三种状态:连接建立.数据传送和连接终止. TCP用三路握手(three-way hand ...
- JS中数组和字符串具有的方法,以及substring,substr和slice的用法与区别
String 对象属性 属性 描述 constructor 对创建该对象的函数的引用 length 字符串的长度 prototype 允许您向对象添加属性和方法 String 对象方法 方法 描述 ...
- 【SPOJ】QTREE6(Link-Cut-Tree)
[SPOJ]QTREE6(Link-Cut-Tree) 题面 Vjudge 题解 很神奇的一道题目 我们发现点有黑白两种,又是动态加边/删边 不难想到\(LCT\) 最爆力的做法,显然是每次修改单点颜 ...
- 埃及分数&&The Rotation Game&&骑士精神——IDA*
IDA*:非常好用的搜索,可以解决很多深度浅,但是规模大的搜索问题. 估价函数设计思路:观察一步最多能向答案靠近多少. 埃及分数 题目大意: 给出一个分数,由分子a 和分母b 构成,现在要你分解成一系 ...
- [JOI 2015 Final] 分蛋糕 2
link 试题分析 容易发现性质,选择的是一段区间,但是贪心无法去维护这件事情,所以考虑$dp$,且我们只要去设计关于$JOI$的选择. 设$dp(i,j)$为现在要在$[l,r]$区间内选择,然后就 ...
- python基础----继承与派生、组合、接口与归一化设计、抽象类、子类中调用父类方法
一.什么是继承 继承是一种创建新的类的方式,在pyth ...