题目链接:http://codeforces.com/problemset/problem/455/D

题意:给定一个长度为n的序列a[]。 m次操作。共有两种操作 1 l r:将序列的a[l].a[l+1]...a[r]变成a[r].a[l].a[l+1]...a[r-1];2 l r k:求序列a[l].a[l+1]...a[r]中有多少个值为k。 输入的l,r,k都是加密过的。所以要解密一下。规则为 l=(l+ans-1)%n+1  r=(r+ans-1)%n+1 k=(k+ans-1)%n+1. (当解密过后l>r时交换l,r)ans为上一个2操作的结果。初始的ans为0. 即题目要求强制在线。

思路:考虑分块。每块维护一个cnt数组,cnt[i]表示在该块中数字i出现的次数。 再维护一个双端队列deque. 然后对于1操作就暴力来修改就好了。注意如果1操作涉及到多块的时候,要将第i块的最后一个移动到第i+1块的第一个。 然后维护一下cnt即可。

#define _CRT_SECURE_NO_DEPRECATE
#include<stdio.h>
#include<string.h>
#include<cstring>
#include<algorithm>
#include<queue>
#include<math.h>
#include<time.h>
#include<vector>
#include<iostream>
#include<map>
using namespace std;
typedef long long int LL;
const int MAXN = + ;
int belong[MAXN], block, num, L[MAXN], R[MAXN];
int n, q, val[MAXN];
struct Node{
deque<int>Q;
int cnt[MAXN];
}Bval[];
void build(){
block = (int)sqrt(n + 0.5);
num = n / block; if (n%block){ num++; }
for (int i = ; i <= num; i++){
memset(Bval[i].cnt, , sizeof(Bval[i].cnt));
Bval[i].Q.clear();
L[i] = (i - )*block + ; R[i] = i*block;
}
R[num] = n;
for (int i = ; i <= n; i++){
belong[i] = ((i - ) / block) + ;
}
for (int i = ; i <= num; i++){
for (int k = L[i]; k <= R[i]; k++){
Bval[i].cnt[val[k]]++;
Bval[i].Q.push_back(val[k]);
}
}
}
void modify(int st, int ed){
deque<int>::iterator it; int v;
if (belong[st] == belong[ed]){
it = Bval[belong[st]].Q.begin();
for (int i = L[belong[st]]; i < ed; i++){
it++;
}
v = *it;
Bval[belong[st]].Q.erase(it);
it = Bval[belong[st]].Q.begin();
for (int i = L[belong[st]]; i<st; i++){
it++;
}
Bval[belong[st]].Q.insert(it, v);
return;
}
it = Bval[belong[ed]].Q.begin();
for (int i = L[belong[ed]]; i < ed; i++){ it++; }
v = *it;
Bval[belong[ed]].Q.erase(it); Bval[belong[ed]].cnt[v]--;
it = Bval[belong[st]].Q.begin();
for (int i = L[belong[st]]; i < st; i++){ it++; }
Bval[belong[st]].Q.insert(it, v); Bval[belong[st]].cnt[v]++;
for (int i = belong[st] + ; i <= belong[ed]; i++){
it = Bval[i - ].Q.end() - ; v = *it;
Bval[i].Q.push_front(v); Bval[i].cnt[v]++;
Bval[i - ].cnt[v]--;
Bval[i - ].Q.erase(it);
}
}
int query(int st, int ed, int v){
int ans = ;
deque<int>::iterator it;
if (belong[st] == belong[ed]){
it = Bval[belong[st]].Q.begin();
for (int i = L[belong[st]]; i<st; i++){
it++;
}
for (int i = st; i <= ed; i++, it++){
ans += ((*it) == v);
}
return ans;
}
it = Bval[belong[st]].Q.begin();
for (int i = L[belong[st]]; i<st; i++){
it++;
}
for (int i = st; i <= R[belong[st]]; i++, it++){
ans += ((*it) == v);
}
for (int i = belong[st] + ; i < belong[ed]; i++){
ans += Bval[i].cnt[v];
}
it = Bval[belong[ed]].Q.begin();
for (int i = L[belong[ed]]; i <= ed; i++, it++){
ans += ((*it) == v);
}
return ans;
}
int main(){
//#ifdef kirito
// freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
//#endif
// int start = clock();
while (~scanf("%d", &n)){
for (int i = ; i <= n; i++){
scanf("%d", &val[i]);
}
build(); scanf("%d", &q);
int type, l, r, v, ans = ;
for (int i = ; i <= q; i++){
scanf("%d", &type);
if (type == ){
scanf("%d%d", &l, &r);
l = ((l + ans - ) % n) + ; r = ((r + ans - ) % n) + ;
if (l>r){ swap(l, r); }
modify(l, r);
}
else{
scanf("%d%d%d", &l, &r, &v);
l = ((l + ans - ) % n) + ; r = ((r + ans - ) % n) + ; v = ((v + ans - ) % n + );
if (l>r){ swap(l, r); }
printf("%d\n", ans = query(l, r, v));
}
}
}
//#ifdef LOCAL_TIME
// cout << "[Finished in " << clock() - start << " ms]" << endl;
//#endif
return ;
}

CodeForces 455D 分块的更多相关文章

  1. Serega and Fun CodeForces - 455D (分块 或 splay)

    大意:给定n元素序列, 2种操作 将区间$[l,r]$循环右移1位 询问$[l,r]$中有多少个等于k的元素 现在给定q个操作, 输出操作2的询问结果, 强制在线 思路1: 分块 每个块内维护一个链表 ...

  2. Codeforces 455D 分块+链表

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

  3. CodeForces 444C 分块

    题目链接:http://codeforces.com/problemset/problem/444/C 题意:给定一个长度为n的序列a[].起初a[i]=i,然后还有一个色度的序列b[],起初b[i] ...

  4. CodeForces 551E 分块

    题目链接:http://codeforces.com/problemset/problem/551/E 题意:给定一个长度为N的序列. 有2个操作 1 l r v:序列第l项到第r项加v(区间加), ...

  5. CodeForces 103D 分块处理

    题目链接:http://codeforces.com/problemset/problem/103/D 题意:给定一个长度为n的序列.然后q个询问.每个询问为(a,b),表示从序列第a项开始每b项的加 ...

  6. Codeforces Round #423 (Div. 2, rated, based on VK Cup Finals) Problem E (Codeforces 828E) - 分块

    Everyone knows that DNA strands consist of nucleotides. There are four types of nucleotides: "A ...

  7. Serega and Fun Codeforces - 455D || queue

    https://codeforces.com/problemset/problem/455/D 其实方法很多,然而当初一个也想不到... 1.分块,块内用链表维护 修改[l,r]就当成删除第r个元素, ...

  8. CodeForces 13E 分块

    题目链接:http://codeforces.com/problemset/problem/13/E 题意:给定n个弹簧和每个弹簧初始的弹力a[].当球落在第i个位置.则球会被弹到i+a[i]的位置. ...

  9. CodeForces - 455D

    Serega loves fun. However, everyone has fun in the unique manner. Serega has fun by solving query pr ...

随机推荐

  1. Alpha阶段第一次Scrum Meeting

    Scrum Meeting   Alpha 情况简述 Alpha阶段第一次Scrum Meeting 敏捷开发起始时间 2016/10/18 00:00 敏捷开发终止时间 2016/10/20 00: ...

  2. iOS 图片大小压缩 图片尺寸处理

    图片的压缩其实是俩概念,1.是 “压” 文件体积变小,但是像素数不变,长宽尺寸不变,那么质量可能下降,2.是 “缩” 文件的尺寸变小,也就是像素数减少.长宽尺寸变小,文件体积同样会减小. 这个 UII ...

  3. VMware 虚拟上网的的三种模式 ——bridged、host-only、NAT 模式

    恐怕这是今年在上海的最后的一篇博客了,同事们上班都不工作了,我也没有什么事情要做.为什么要写这篇博客呢,原因是我回家要带上自己的笔记本,里面装了一个虚拟机.平时自己的学习和工作都是在虚拟机里进行的.回 ...

  4. apache2.4 绿色版环境配置。

    http://jingyan.baidu.com/article/9faa723152c5d6473d28cb47.html http://jingyan.baidu.com/article/9faa ...

  5. C# 调用WebService的3种方式 :直接调用、根据wsdl生成webservice的.cs文件及生成dll调用、动态调用

    1.直接调用 已知webservice路径,则可以直接 添加服务引用--高级--添加web引用 直接输入webservice URL.这个比较常见也很简单 即有完整的webservice文件目录如下图 ...

  6. 面试题目——《CC150》链表

    面试题2.1:编写代码,移除未排序链表中的重复结点 进阶:如果不得使用临时缓冲区,该怎么解决? package cc150; import java.util.HashMap; import java ...

  7. .Net创建windows服务入门

    本文主要记录学习.net 如何创建windows服务. 1.创建一个Windows服务程序 2.新建安装程序 3.修改service文件 代码如下 protected override void On ...

  8. Silicon C8051F340之时钟系统

    一.背景 做个记录,以备下次快速开发. 二.正文 C8051F340有一个可编程内部高频振荡器.一个可编程内部低频振荡器.一个外部振荡器驱动电路 和一个4倍时钟乘法器.其中可编程内部高频振荡器在系统复 ...

  9. Marquee 滚动参数

    new marquee("Layer3", 2, 1, 989, 68, 20, 0, 0, 238); 参数说明:Layer3 :容器ID 2 :向上滚动(0向上 1向下 2向左 ...

  10. git 教程(14)--解决冲突

    人生不如意之事十之八九,合并分支往往也不是一帆风顺的. 准备新的feature1分支,继续我们的新分支开发: