[置顶] CodeForces 455D Serega and Fun (分块+双端队列)
2016-10-12 11:35
411 查看
题意:给出一个序列,两种操作
1.将区间[l,r]滚动一次
2.询问区间[l,r]中值等于k的数有多少个
在线
分块之后,两种操作都能在sqrt(n)的复杂度内解决,将每个块都设置为队列,这样滚动起来非常方便
一开始没有看到数值的范围,直接用的分块+bitset+双端队列,结果T了,后来看到了这一点,想写个分块+循环队列,结果发现编程复杂度太高..(好菜)…最终还是分块+双端队列…
1.将区间[l,r]滚动一次
2.询问区间[l,r]中值等于k的数有多少个
在线
分块之后,两种操作都能在sqrt(n)的复杂度内解决,将每个块都设置为队列,这样滚动起来非常方便
一开始没有看到数值的范围,直接用的分块+bitset+双端队列,结果T了,后来看到了这一点,想写个分块+循环队列,结果发现编程复杂度太高..(好菜)…最终还是分块+双端队列…
#include<cstring> #include<iostream> #include<cstdio> #include<algorithm> #include<queue> #include<cmath> using namespace std; #define maxn 100005 int n,m; int b[350][maxn]; deque<int>que[350]; int val[maxn]; int block,num,belong[maxn],l[maxn],r[maxn]; void init() { block=sqrt(n); num=n/block; if(n&block) num++; for(int i=1; i<=n; i++) { belong[i]=(i-1)/block+1; } for(int i=1; i<=num; i++) { l[i]=(i-1)*block+1; r[i]=i*block; } r[num]=n; for(int i=1; i<=num; i++) { for(int j=l[i]; j<=r[i]; j++) { b[i][val[j]]++; que[i].push_back(val[j]); } } } void update(int x,int y) { if(belong[x]==belong[y]) { int index=belong[x]; x-=l[index]; y-=l[index]; int temp=que[index][y]; for(int i=y; i>x; i--) { que[index][i]=que[index][i-1]; } que[index][x]=temp; return ; } int temp=que[belong[y]][y-l[belong[y]]]; int temp2=que[belong[x]][r[belong[x]]-l[belong[x]]]; b[belong[x]][temp2]--; b[belong[y]][temp]--; for(int i=r[belong[x]]; i>x; i--) { que[belong[x]][i-l[belong[x]]]=que[belong[x]][i-l[belong[x]]-1]; } que[belong[x]][x-l[belong[x]]]=temp; b[belong[x]][temp]++; for(int i=belong[x]+1; i<belong[y]; i++) { int tp=temp2; b[i][temp2]++; temp2=que[i][r[i]-l[i]]; que[i].pop_back(); que[i].push_front(tp); b[i][temp2]--; } for(int i=y; i>l[belong[y]]; i--) { que[belong[y]][i-l[belong[y]]]=que[belong[y]][i-l[belong[y]]-1]; } que[belong[y]][0]=temp2; b[belong[y]][temp2]++; } int query(int x,int y,int k) { int ans=0; if(belong[x]==belong[y]) { for(int i=x; i<=y; i++) { if(que[belong[x]][i-l[belong[x]]]==k) ans++; } return ans; } for(int i=x; i<=r[belong[x]]; i++) { if(que[belong[x]][i-l[belong[x]]]==k) ans++; } for(int i=belong[x]+1; i<belong[y]; i++) { ans+=b[i][k]; } for(int i=l[belong[y]]; i<=y; i++) { if(que[belong[y]][i-l[belong[y]]]==k) ans++; } return ans; } int main() { scanf("%d",&n); for(int i=1; i<=n; i++) { scanf("%d",&val[i]); } init(); scanf("%d",&m); int ans=0; while(m--) { int op; scanf("%d",&op); int x,y; scanf("%d%d",&x,&y); x=(x+ans-1)%n+1; y=(y+ans-1)%n+1; if(x>y) swap(x,y); if(op==1) { update(x,y); } else if(op==2) { int k; scanf("%d",&k); k=(k+ans-1)%n+1; printf("%d\n",ans=query(x,y,k)); } } }
相关文章推荐
- [置顶] CodeForces 551E GukiZ and GukiZiana (分块)
- Codeforces-898D:Alarm Clock(双端队列)
- codeforces 251A Points on Line(二分or单调队列)
- 【CodeForces】80D Time to Raid Cowavans 分块
- POJ 2823(双端队列)
- 经典算法题每日演练——第十九题 双端队列
- Java 模拟队列(一般队列、双端队列、优先级队列)
- 详解Python的collections模块中的deque双端队列结构
- [置顶] 用队列ConcurrentLinkedQueue模拟生产者和消费者
- 双端队列
- [置顶] HDU 4123 (树的直径+单调队列求差值小于等于k的最长子区间)
- [置顶] spring boot 使用activeMQ实现消息队列简单应用
- CodeForces 660C Hard Process (队列)
- POJ2823 Sliding Window【双端队列】
- stl之deque双端队列容器
- Java 集合深入理解(10):Deque 双端队列
- 【双端队列】滑动的窗户 window
- POJ-2823--Sliding Window--双端队列实现单调队列
- 队列的应用:双端队列
- 【BZOJ】2453: 维护队列【BZOJ】2120: 数颜色 二分+分块(暴力能A)