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,如果有比他年轻的大象排在他前面,这头大象就会非常 ...
随机推荐
- UVA1378 A Funny Stone Game —— SG博弈
题目链接:https://vjudge.net/problem/UVA-1378 题意: 两个人玩游戏,有n堆石子,两人轮流操作:于第i堆石子中取走一块石子,然后再往第j.k堆中各添加一块石子.其中 ...
- spring mvc提交日期类型参数
如题,spring mvc直接提交Date类型参数会报错,400 bad request的错误.在controller里加上 @InitBinder protected void initBinder ...
- python 快速排序 qsort
def qsort(arr, start, end): if start > end: return def partition(arr, start, end): pivot = arr[st ...
- 启动jmeter报错
启动jmeter.bat时报错
- Eclipse 插件使用
1. AmaterasUML:UML 类图(class diagram) 注意这里是先编写好代码,通过插件根据代码逻辑关系生成类图: 安装AmaterasUML前,需要先安装 GEF,采用 eclip ...
- 「BZOJ3083」遥远的国度(树剖换根
3083: 遥远的国度 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 4859 Solved: 1372[Submit][Status][Discu ...
- bootstrap table 根据单元格中的数据改变单元格的样式
在bootstrap-table.js里面列属性 formatter就是用来格式化单元格的,其默认值是undefined 类型是function,function(value, row, index ...
- Azure AD (6) 停止Azure AD Connect Sync同步,并删除自定义域名
<Windows Azure Platform 系列文章目录> 如果你已经了解了我之前写的文章:Azure AD (5) 在单一目录下,使用Azure AD单点登录 应该对使用Azure ...
- Gulp简单应用
1.创建一个工程,在webstorm控制台 cnpm install --save-dev gulp cnpm install --save-dev gulp-concat ...
- Codeforces 1108E2 Array and Segments (Hard version) 差分, 暴力
Codeforces 1108E2 E2. Array and Segments (Hard version) Description: The only difference between eas ...