Serega and Fun Codeforces - 455D || queue
https://codeforces.com/problemset/problem/455/D
其实方法很多,然而当初一个也想不到...
1.分块,块内用链表维护
修改[l,r]就当成删除第r个元素,在第l个元素之前插入删掉的元素:就找到r删除,然后调整各个块的结构(对于[block[l]+1,block[r]]中的每个块,把它之前一块的最后一个元素移到自身块的第一个元素),然后找到l应该插入的位置并插入l
修改的同时,维护一下各个块中各个元素出现的次数
查询应该没什么问题了。。。
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
#define fi first
#define se second
#define mp make_pair
#define pb push_back
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
const int bs=;
int cnt;//块数
struct E
{
int pre,nxt;int d;
}e[];
int he[],ta[];//head,tail
int bl[],st[],ed[];
int num[][];
void add_tail(int b,int x)
{
if(!ta[b])
{
he[b]=ta[b]=x;
}
else
{
e[ta[b]].nxt=x;e[x].pre=ta[b];
ta[b]=x;
}
++num[b][e[x].d];
}
int remove_tail(int b)
{
int t=ta[b];
--num[b][e[t].d];
if(he[b]==ta[b])
{
he[b]=ta[b]=;
}
else
{
ta[b]=e[t].pre;
e[e[t].pre].nxt=;e[t].pre=;
}
return t;
}
void add_head(int b,int x)
{
if(!he[b])
{
he[b]=ta[b]=x;
}
else
{
e[he[b]].pre=x;e[x].nxt=he[b];
he[b]=x;
}
++num[b][e[x].d];
}
void ins_before(int b,int x,int y)//ins x to b before y
{
if(!he[b])
{
he[b]=ta[b]=x;
}
else if(y==he[b])
{
e[y].pre=x;
e[x].nxt=y;
he[b]=x;
}
else if(!y)
{
e[ta[b]].nxt=x;
e[x].pre=ta[b];
ta[b]=x;
}
else
{
e[e[y].pre].nxt=x;
e[x].pre=e[y].pre;
e[y].pre=x;
e[x].nxt=y;
}
}
int qq;
int n,an,lans;
int main()
{
//freopen("/tmp/YALI(10-23)/sample/queue/queue1.in","r",stdin);
//freopen("/tmp/YALI(10-23)/sample/queue/queue1.out","w",stdout);
int i,j,t,l,r,x,nl,nr,nt,b,idx;
scanf("%d",&n);
for(i=;i<=n;i++)
{
scanf("%d",&t);
bl[i]=(i-)/bs;
e[i].d=t;
}
cnt=(n-)/bs;
for(i=;i<cnt;i++)
{
st[i]=bs*i+;
ed[i]=bs*(i+);
}
st[cnt]=bs*cnt+;ed[cnt]=n;
for(i=;i<=n;i++) add_tail(bl[i],i);
scanf("%d",&qq);
while(qq--)
{
scanf("%d",&idx);
if(idx==)
{
scanf("%d%d",&l,&r);
l=(l+lans-)%n+;
r=(r+lans-)%n+;
if(l>r) swap(l,r);
/*
if(bl[l]==bl[r])
{
b=bl[r];
nr=he[b];
for(j=st[b]+1;j<=r;j++)
nr=e[nr].nxt; }
else
*/
{
b=bl[r];
nr=he[b];
for(j=st[b]+;j<=r;j++)
nr=e[nr].nxt;
if(nr==he[b]) he[b]=e[nr].nxt;
else e[e[nr].pre].nxt=e[nr].nxt;
if(nr==ta[b]) ta[b]=e[nr].pre;
else e[e[nr].nxt].pre=e[nr].pre;
e[nr].pre=e[nr].nxt=;
--num[b][e[nr].d];
b=bl[l];
for(j=bl[r];j>b;j--)
{
nt=remove_tail(j-);
add_head(j,nt);
}
if(l==ed[b])
{
nl=;
}
else
{
nl=ta[b];
for(j=ed[b]-;j>=l;j--)
nl=e[nl].pre;
}
ins_before(b,nr,nl);
++num[b][e[nr].d];
}
}
else
{
scanf("%d%d%d",&l,&r,&x);
l=(l+lans-)%n+;
r=(r+lans-)%n+;
x=(x+lans-)%n+;
if(l>r) swap(l,r);
an=;
if(bl[l]==bl[r])
{
b=bl[l];
nl=he[b];
for(j=st[b]+;j<=l;j++)
nl=e[nl].nxt;
for(j=l;j<=r;j++)
{
an+=(e[nl].d==x);
nl=e[nl].nxt;
}
}
else
{
for(j=bl[l]+;j<=bl[r]-;j++)
an+=num[j][x];
b=bl[r];
nr=he[b];
an+=(e[nr].d==x);
for(j=st[b]+;j<=r;j++)
{
nr=e[nr].nxt;
an+=(e[nr].d==x);
}
b=bl[l];
nl=ta[b];
an+=(e[nl].d==x);
for(j=ed[b]-;j>=l;j--)
{
nl=e[nl].pre;
an+=(e[nl].d==x);
}
}
lans=an;
printf("%d\n",an);
}
}
return ;
}
2.分块,定期重构(官方题解)
跟方法1大部分一样,但是块内不用链表,直接用vector或者数组,插入/删除就暴力,同时维护各个块中各个元素出现次数,然后每sqrt(n)次重构所有块
3.平衡树(见官方题解下面的第一条评论)
(额外解释:为什么是n*log^2而不是n*log呢?因为所有的下标都是动态的。询问(l,r,k)时,需要在k-splay中找出有多少个点下标在[l,r]内,而每一次查询下标必须要在0-splay中查询一下(注意下标是动态的,不能直接记下下标))
http://210.33.19.103/contest/1025/problem/3
此题同C.queue
Serega and Fun Codeforces - 455D || queue的更多相关文章
- Serega and Fun CodeForces - 455D (分块 或 splay)
大意:给定n元素序列, 2种操作 将区间$[l,r]$循环右移1位 询问$[l,r]$中有多少个等于k的元素 现在给定q个操作, 输出操作2的询问结果, 强制在线 思路1: 分块 每个块内维护一个链表 ...
- CodeForces 455D 分块
题目链接:http://codeforces.com/problemset/problem/455/D 题意:给定一个长度为n的序列a[]. m次操作.共有两种操作 1 l r:将序列的a[l].a[ ...
- codeforces D. Queue 找规律+递推
题目链接: http://codeforces.com/problemset/problem/353/D?mobile=true H. Queue time limit per test 1 seco ...
- CodeForces - 455D
Serega loves fun. However, everyone has fun in the unique manner. Serega has fun by solving query pr ...
- CodeForces 91B Queue (线段树,区间最值)
http://codeforces.com/problemset/problem/91/B B. Queue time limit per test: 2 seconds memory limit p ...
- codeforces 490B.Queue 解题报告
题目链接:http://codeforces.com/problemset/problem/490/B 题目意思:给出每个人 i 站在他前面的人的编号 ai 和后面的人的编号 bi.注意,排在第一个位 ...
- Codeforces 353D Queue(构造法)
[题目链接] http://codeforces.com/contest/353/problem/D [题目大意] 10^6个男女排队,每一秒,如果男生在女生前面,即pos[i]是男生,pos[i+1 ...
- Codeforces 490B Queue【模拟】
题意还是很好理解的,根据题目给出描述条件然后求出这串QUEUE 我的做法就是用两个数组 before[] 和 after[] 表示 ai 前面的前面的人的学号 和 ai 后面的后面的人的学号 ex[] ...
- CodeForces 91B Queue
题目链接:http://codeforces.com/contest/91/problem/B 题目大意: 有n头大象排队买票,第i头大象的年龄为ai,如果有比他年轻的大象排在他前面,这头大象就会非常 ...
随机推荐
- buntu下命令行安装jdk,android-studio,及genymotion虚拟机来进行android开发【转】
本文转载自:http://www.cnblogs.com/iamhenanese/p/5491862.html 安装JDK 从oracle官网下最新版的linux64位的jdk包(现在最新为jdk-8 ...
- 安装python解释器
Python目前已支持所有主流操作系统,在Linux,Unix,Mac系统上自带Python环境,在Windows系统上需要安装一下,超简单 打开官网 https://www.python.org/d ...
- html5--3.4 input元素(3)
html5--3.4 input元素(3) 学习要点 input元素及其属性 input元素 用来设置表单中的内容项,比如输入内容的文本框,按钮等 不仅可以布置在表单中,也可以在表单之外的元素使用 i ...
- codeforces 569D D. Symmetric and Transitive(bell数+dp)
题目链接: D. Symmetric and Transitive time limit per test 1.5 seconds memory limit per test 256 megabyte ...
- [LeetCode] Shortest Distance from All Buildings Solution
之前听朋友说LeetCode出了一道新题,但是一直在TLE,我就找时间做了一下.这题是一个比较典型的BFS的题目,自己匆忙写了一个答案,没有考虑优化的问题,应该是有更好的解法的. 原题如下: You ...
- Python框架下django 的并发和多线程
django 的并发能力真的是令人担忧,django本身框架下只有一个线程在处理请求,任何一个请求阻塞,就会影响另一个情感求的响应,尤其是涉及到IO操作时,基于框架下开发的视图的响应并没有对应的开启多 ...
- 利用Powershell在IIS上自动化部署网站
本文主要讲如何通过Powershell在IIS上自动化部署ASP.NET网站,而不涉及Powershell的基本语法,如果没有Powershell基础的同学也可以把本文作为学习Powershell的基 ...
- 查看Ubuntu的版本
方法一: cat /etc/issue 方法二: lsb_release -a
- calico在docker上的部署及验证
1. 背景 以下的部署以五台服务器环境为例: 服务器1: hostname为etcdnode1, IP为192.168.56.100 服务器2: hostname为etcdnode2, IP为192. ...
- HDOJ-2058
The sum problem Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)T ...