题意:

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

思路:

1.

每块用一个链表维护一下
位移的话由于是链表,操作速度很快
然后每个数都不超过 N,所以用一个数组记录一下每块每个数的个数
总的复杂度就是 O(Qsqrt(N))

2.

如果不考虑那个奇怪的询问的话,可以简单地用splay树维护序列。但是splay上显然不能维护每种颜色的个数,这样在每个节点上时间和空间都是O(n)的。
我们把给每种颜色的节点单独建一棵splay,每个节点放在两棵splay中,一棵是原序列,一棵是它自己的颜色。接下来考虑如何进行插入、询问和删除操作。
删除操作比较简单,只需要在大splay上找到对应的节点,在两棵树中先旋转到底再自下而上删除。
插入和询问都可以在小splay上走,通过在大splay上的询问就可以知道当前节点在序列中的位置。
复杂度O((n+q)log2n)。

from yhx


//By SiriusRen
#include <bits/stdc++.h>
using namespace std;
const int N=;
int n,q,a[N],wei[][N],l[],r[],block[N],lastans;
list<int>lst[];
list<int>::iterator it,it2;
void make_list(){
for(int i=;i<=block[n];i++)
for(int j=l[i];j<=r[i];j++)
lst[i].push_back(a[j]),wei[i][a[j]]++;
}
void work(int x,int y){
int t=y-l[block[y]],tmp,rem;
for(it=lst[block[y]].begin();t;t--,it++);
rem=*it;wei[block[y]][rem]--;
lst[block[y]].erase(it);
for(int i=block[x];i<block[y];i++){
it=lst[i].end(),it--,tmp=*it,lst[i].erase(it);
lst[i+].push_front(tmp);
wei[i][tmp]--,wei[i+][tmp]++;
}
t=x-l[block[x]];
for(it=lst[block[x]].begin();t;t--,it++);
lst[block[x]].insert(it,rem);wei[block[x]][rem]++;
}
int query(int x,int y,int z){
int ans=,t=x-l[block[x]],ty;
if(block[x]==block[y]){
for(it=lst[block[x]].begin();t;t--,it++);
ty=y-l[block[y]]+;
for(it2=lst[block[x]].begin();ty;ty--,it2++);
for(;it!=it2;it++){if(*it==z)ans++;}
return ans;
}
for(int i=block[x]+;i<block[y];i++)ans+=wei[i][z];
for(it=lst[block[x]].begin();t;t--,it++);
for(;it!=lst[block[x]].end();it++)if(*it==z)ans++;
t=y-l[block[y]]+;
for(it=lst[block[y]].begin();t;it++,t--)if(*it==z)ans++;
return ans;
}
int main(){
memset(l,0x3f,sizeof(l)),scanf("%d",&n);
for(int i=;i<=n;i++)scanf("%d",&a[i]);
int Block=1.6*sqrt(n);
for(int i=;i<=n;i++)block[i]=(i-)/Block+,l[block[i]]=min(l[block[i]],i),r[block[i]]=i;
make_list();
scanf("%d",&q);
while(q--){
int op,xx,yy,zz;
scanf("%d%d%d",&op,&xx,&yy);
xx=(xx+lastans-)%n+,yy=(yy+lastans-)%n+;
if(xx>yy)swap(xx,yy);
if(op==)work(xx,yy);
else scanf("%d",&zz),printf("%d\n",lastans=query(xx,yy,(zz+lastans-)%n+));
}
}

最新文章

  1. UVa 10129单词(欧拉回路)
  2. android网络框架Retrofit 同步异步
  3. 解析XML的几种方法之SAX解析
  4. JavaScript系列:常用方法
  5. yii项目开发项目常用技巧和方法汇总
  6. [原]逆向iOS SDK -- +[UIImage imageNamed:] 的实现
  7. easyui框架--基础篇(一)--&gt;数据表格datagrid(php与mysql交互)
  8. Windows下pip 离线包安装
  9. python 实现rsa 的加密解密存读取(PEM格式证书)【转发】
  10. [ovs] 编写openflow流表的文档指引
  11. Mac ssh 免密码登录 Mac 或者 Linux
  12. idea报错:[2016-08-31 09:20:10,763] Artifact xxx:war exploded: Error during artifact deployment.
  13. 用户输入序号选择商品,按q退出
  14. 结构体内嵌比较函数bool operator &lt; (const node &amp;x) const {}
  15. 【转】深入浅出JMS(三)--ActiveMQ简单的HelloWorld实例
  16. git使用基本教程
  17. Luogu P1314 聪明的质监员 二分答案
  18. python利用paramiko连接远程服务器执行命令
  19. The OpenCV Coding Style Guide
  20. 自动化测试调查问卷送《QTP自动化测试最佳实践》

热门文章

  1. buf.readIntBE()
  2. 洛谷 1472 奶牛家谱 Cow Pedigrees
  3. mysql数据库变更监控(canal)
  4. 创建Maven版Java工程
  5. 【05】JSON笔记
  6. mongodb数据库的一些常用命令列表
  7. hdu 2647拓扑排序 结构体模拟容器
  8. hdu3303
  9. CodeForces 370C
  10. 这段百度问答,对我相关有对啊!!!----如何获取Windows系统登陆用户名