Codeforces 455D Serega and Fun【解法一】
来源:互联网 发布:大数据时代下的教育 编辑:程序博客网 时间:2024/06/13 20:41
如果不考虑那个奇怪的询问的话,可以简单地用splay树维护序列。但是splay上显然不能维护每种颜色的个数,这样在每个节点上时间和空间都是
我们把给每种颜色的节点单独建一棵splay,每个节点放在两棵splay中,一棵是原序列,一棵是它自己的颜色。接下来考虑如何进行插入、询问和删除操作。
删除操作比较简单,只需要在大splay上找到对应的节点,在两棵树中先旋转到底再自下而上删除。
插入和询问都可以在小splay上走,通过在大splay上的询问就可以知道当前节点在序列中的位置。
复杂度
#include<cstdio>#include<algorithm>using namespace std;const int maxn=400010;int a[maxn],rt[maxn],val[maxn],size[2][maxn],son[2][maxn][2],fa[2][maxn],num[maxn],n,q,tot;void upd(int u,int f){ size[f][u]=size[f][son[f][u][0]]+size[f][son[f][u][1]]+1;}void rot(int u,int f1,int f2){ int v=son[f2][u][f1],x=son[f2][v][f1^1],f=fa[f2][u]; fa[f2][v]=f; if (f) son[f2][f][son[f2][f][1]==u]=v; else { if (f2) rt[val[u]]=v; else rt[0]=v; } son[f2][v][f1^1]=u; fa[f2][u]=v; son[f2][u][f1]=x; if (x) fa[f2][x]=u; upd(u,f2); upd(v,f2);}void splay(int u,int f){ int x1,x2,f1,f2; while (fa[f][u]) { x1=fa[f][u]; f1=(son[f][x1][1]==u); if (!fa[f][x1]) rot(x1,f1,f); else { x2=fa[f][x1]; f2=(son[f][x2][1]==x1); if (f1==f2) rot(x2,f2,f),rot(x1,f1,f); else rot(x1,f1,f),rot(x2,f2,f); } }}int getrank(int u){ if (!u) return 0; splay(u,0); return size[0][son[0][u][0]]+1;}int getkth(int u,int k){ int x=size[0][son[0][u][0]]; if (x>=k) return getkth(son[0][u][0],k); if (x+1==k) { splay(u,0); return u; } return getkth(son[0][u][1],k-x-1);}void ins0(int u,int v,int k){ size[0][u]++; if (size[0][son[0][u][0]]>=k-1) { if (son[0][u][0]) ins0(son[0][u][0],v,k); else son[0][u][0]=v,fa[0][v]=u; } else { if (son[0][u][1]) ins0(son[0][u][1],v,k-size[0][son[0][u][0]]-1); else son[0][u][1]=v,fa[0][v]=u; }}void ins1(int u,int v,int k){ size[1][u]++; if (getrank(u)>=k) { if (son[1][u][0]) ins1(son[1][u][0],v,k); else son[1][u][0]=v,fa[1][v]=u; } else { if (son[1][u][1]) ins1(son[1][u][1],v,k); else son[1][u][1]=v,fa[1][v]=u; }}void Insert(int u,int k){ size[0][u]=size[1][u]=1; fa[0][u]=fa[1][u]=son[0][u][0]=son[0][u][1]=son[1][u][0]=son[1][u][1]=0; if (!rt[val[u]]) rt[val[u]]=u; else ins1(rt[val[u]],u,k); splay(u,1); if (!rt[0]) rt[0]=u; else ins0(rt[0],u,k); splay(u,0);}void del(int u,int f){ while (son[f][u][0]&&son[f][u][1]) rot(u,size[f][son[f][u][0]]>size[f][son[f][u][1]],f); for (int i=fa[f][u];i;i=fa[f][i]) size[f][i]--; int v=son[f][u][0]+son[f][u][1],r=(f?val[u]:0); if (rt[r]==u) { rt[r]=v; fa[f][v]=0; } else { if (v) fa[f][v]=fa[f][u]; son[f][fa[f][u]][son[f][fa[f][u]][1]==u]=v; } splay(v,f);}void Delete(int u){ del(u,1); del(u,0);}int qry(int u,int k){ int x=getrank(u),ret; if (x>k) { ret=0; if (son[1][u][0]) ret+=qry(son[1][u][0],k); else splay(u,1); } else { ret=size[1][son[1][u][0]]+1; if (son[1][u][1]) ret+=qry(son[1][u][1],k); else splay(u,1); } return ret;}int main(){ //freopen("b.in","r",stdin); int last=0,u,opt,l,r,k; scanf("%d",&n); for (int i=1;i<=n;i++) { scanf("%d",&val[i]); Insert(i,i); } scanf("%d",&q); while (q--) { scanf("%d%d%d",&opt,&l,&r); l=(l+last-1)%n+1,r=(r+last-1)%n+1; if (l>r) swap(l,r); if (opt==1) { u=getkth(rt[0],r); Delete(u); Insert(u,l); } else { scanf("%d",&k); k=(k+last-1)%n+1; printf("%d\n",last=(qry(rt[k],r)-qry(rt[k],l-1))); } }}
阅读全文
0 0
- Codeforces 455D Serega and Fun【解法一】
- Codeforces 455D Serega and Fun【解法二】
- 【分块】 codeforces 455D - Serega and Fun
- [Codeforces 455D] Serega and Fun (分块)
- 【CodeForces】455D Serega and Fun 双向链表分块暴力
- CodeForces 455D Serega and Fun (分块+双端队列)
- codeforces 455 D. Serega and Fun (分块+双向链表)
- [Codeforces455D]Serega and Fun(分块+双向链表)
- CodeForces 548BMike and Fun
- CodeForces 548B Mike and Fun
- CodeForces 548B Mike and Fun
- 【codeforces 548B】Mike and Fun
- 【Codeforces Round #389】Codeforces 752E Santa Claus and Tangerines【解法一】
- Codeforces Round #219 (Div. 2) D. Counting Rectangles is Fun
- Codeforces 373D Counting Rectangles is Fun【Dp】
- Codeforces Round #305 (Div. 2) B.Mike and Fun
- Codeforces Round #305 (Div. 2) B. Mike and Fun(水题)
- Codeforces Round #305 (Div. 2)B. Mike and Fun
- <select>设置css height兼容性,兼容FF/IE/Safari/Chrome...
- 51nod 1799 二分答案
- MySQL慢查询日志
- Java数据库数据比较问题
- 纯win32实现录音器并播放功能
- Codeforces 455D Serega and Fun【解法一】
- 布局管理器——帧布局
- JDK动态代理源码分析之一
- Henri Bergson and the Perception of Time
- hdu5113 剪枝搜索
- 离线求LCA(深搜)
- MySQL存储引擎总结
- 函数的分装
- 【面试必读(编程基础)】网络游戏同步方式(帧同步和状态同步)