Codeforces 455D 分块+链表
题意:
给定一个长度为 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+));
}
}
Codeforces 455D 分块+链表的更多相关文章
- CodeForces 455D 分块
题目链接:http://codeforces.com/problemset/problem/455/D 题意:给定一个长度为n的序列a[]. m次操作.共有两种操作 1 l r:将序列的a[l].a[ ...
- Serega and Fun CodeForces - 455D (分块 或 splay)
大意:给定n元素序列, 2种操作 将区间$[l,r]$循环右移1位 询问$[l,r]$中有多少个等于k的元素 现在给定q个操作, 输出操作2的询问结果, 强制在线 思路1: 分块 每个块内维护一个链表 ...
- Serega and Fun Codeforces - 455D || queue
https://codeforces.com/problemset/problem/455/D 其实方法很多,然而当初一个也想不到... 1.分块,块内用链表维护 修改[l,r]就当成删除第r个元素, ...
- CodeForces 444C 分块
题目链接:http://codeforces.com/problemset/problem/444/C 题意:给定一个长度为n的序列a[].起初a[i]=i,然后还有一个色度的序列b[],起初b[i] ...
- CodeForces 551E 分块
题目链接:http://codeforces.com/problemset/problem/551/E 题意:给定一个长度为N的序列. 有2个操作 1 l r v:序列第l项到第r项加v(区间加), ...
- CodeForces 103D 分块处理
题目链接:http://codeforces.com/problemset/problem/103/D 题意:给定一个长度为n的序列.然后q个询问.每个询问为(a,b),表示从序列第a项开始每b项的加 ...
- 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 ...
- 【CF896E】Welcome home, Chtholly 暴力+分块+链表
[CF896E]Welcome home, Chtholly 题意:一个长度为n的序列ai,让你支持两种操作: 1.l r x:将[l,r]中ai>x的ai都减去x.2.l r x:询问[l,r ...
- 51nod 1471 小S的兴趣 | 分块 链表
51nod 1471 小S的兴趣 题面 小S喜欢有趣的事.但是,每个人的兴趣都是独特的.小S热衷于自问自答.有一天,小S想出了一个问题. 有一个包含n个正整数的数组a和针对这个数组的几个问题.这些问题 ...
随机推荐
- PHP上传文件到七牛(Qiniu)
上传文件到七牛最简单的方式就是使用七牛官方最新的SDK 安装PHP SDK composer require qiniu/php-sdk 上传文件到七牛 use Qiniu\Auth; use Qin ...
- Java 数组中寻找最大子数组
程序设计思想: 依次将数组划分开,先判断一个元素的单个数组大小,接下来两个,依次上升,最后将所得结果进行比较赋值,输出最大结果. 1 package ketangTest; //张生辉,康治家 201 ...
- 关于pom.xml中的dependency中的顺序
特别注意: <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>l ...
- JavaSE 学习笔记之Jdk5.0新特性(十九)
Jdk5.0新特性: Collection在jdk1.5以后,有了一个父接口Iterable,这个接口的出现的将iterator方法进行抽取,提高了扩展性. --------------------- ...
- java中split以。点和|分割的问题
问题:想要按照点来切分字符串直接这样 String[] filep=filename.split("."); 结果得到一个空数组 解决方法: 法一:需要转义,改为:(注意是2个\\ ...
- centos7 安装mongodb3.4 及用户管理
https://docs.mongodb.com/manual/tutorial/install-mongodb-on-red-hat/1.semanage command not found yum ...
- SpringMvc切面校验JavaBean及基础类型
先配置好aop需要的配置,文:https://www.cnblogs.com/jiangxishicheng/p/10896498.html 编写校验切面类: package com.aspect;/ ...
- 1048 石子归并codevs
1048 石子归并codevs 题目描述 Description 有n堆石子排成一列,每堆石子有一个重量w[i], 每次合并可以合并相邻的两堆石子,一次合并的代价为两堆石子的重量和w[i]+w[i+1 ...
- How can I add files to a Jar file? (or add a file to a zip archive)
https://stackoverflow.com/questions/12239764/how-can-i-add-files-to-a-jar-file M.java class M{ publi ...
- xul 创建一个按钮
MDN Mozilla 产品与私有技术 Mozilla 私有技术 XUL Toolbars 添加工具栏按钮 (定制工具栏) 添加工具栏按钮 (定制工具栏) 在本文章中 创建一个 overlay 在工具 ...