BZOJ3223&3224 文艺&普通平衡树 Splay模板(数组)
2016-03-22 17:34
357 查看
才发现自己splay的模板又臭又长,还自带大常数,而且指针不会调,换回数组,从新打了一遍
区间翻转:
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using namespace std; int read() { int x=0,f=1; char ch=getchar(); while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();} while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();} return x*f; } #define maxn 101000 #define inf 1000000000 int son[maxn][2],fa[maxn],key[maxn],size[maxn],rev[maxn],sz,root; int n,m,a[maxn]={0}; void update(int x) { size[x]=size[son[x][1]]+size[son[x][0]]+1; } void swap(int &x,int &y) { int tmp=x;x=y;y=tmp; } void pushdown(int x) { if (!x || !rev[x]) return; rev[son[x][0]]^=1; rev[son[x][1]]^=1; swap(son[x][0],son[x][1]); rev[x]=0; } int build(int left,int right,int f) { if (left>right) return 0; int mid=(left+right)>>1; int now=++sz; key[now]=a[mid]; fa[now]=f; rev[now]=0; int leftchild=build(left,mid-1,now); int rightchild=build(mid+1,right,now); son[now][0]=leftchild; son[now][1]=rightchild; update(now); return now; } int get(int x) { return son[fa[x]][1]==x; } void rotate(int x) { pushdown(fa[x]); pushdown(x); int old=fa[x],oldf=fa[old],which=get(x); son[old][which]=son[x][which^1]; fa[son[old][which]]=old; fa[old]=x; son[x][which^1]=old; fa[x]=oldf; if (oldf) son[oldf][son[oldf][1]==old]=x; update(old); update(x); } void splay(int x,int tar) { for (int f; (f=fa[x])!=tar; rotate(x)) if (fa[f]!=tar) rotate(get(x)==get(f)?f:x); if (tar==0) root=x; } int find(int x) { int now=root; while (true) { pushdown(now); if (x<=size[son[now][0]]) now=son[now][0]; else { x-=size[son[now][0]]+1; if (x==0) return now; now=son[now][1]; } } return -1; } void print(int now) { pushdown(now); if (son[now][0]) print(son[now][0]); if (key[now]!=inf && key[now]!=-inf) printf("%d ",key[now]); if (son[now][1]) print(son[now][1]); } int main() { n=read(),m=read(); a[1]=-inf; a[n+2]=inf; for (int i=1; i<=n; i++) a[i+1]=i; root=build(1,n+2,0); for (int i=1;i<=m;i++) { int x=read(),y=read(); if (x>=y) continue; int aa=find(x); int bb=find(y+2); splay(aa,0); splay(bb,aa); rev[son[son[root][1]][0]]^=1; } print(root); printf("\n"); return 0; }
插入,删除,前驱,后继,编号为k的值,排名为k的值:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; int read() { int x=0,f=1; char ch=getchar(); while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();} while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();} return x*f; } #define maxn 1000010 int n,m; int fa[maxn],son[maxn][2],key[maxn],cnt[maxn],size[maxn]; int sz,root; void clear(int now) { son[now][1]=son[now][0]=fa[now]=cnt[now]=key[now]=size[now]; } int get(int now) { return son[fa[now]][1]==now; } void update(int now) { if (!now) return; size[now]=cnt[now]; if (son[now][0]) size[now]+=size[son[now][0]]; if (son[now][1]) size[now]+=size[son[now][1]]; } void rotate(int now) { int old=fa[now],oldf=fa[old],which=get(now); son[old][which]=son[now][which^1]; fa[son[old][which]]=old; fa[old]=now; son[now][which^1]=old; fa[now]=oldf; if (oldf) son[oldf][son[oldf][1]==old]=now; update(old); update(now); } void splay(int now) { for (int f; (f=fa[now]); rotate(now)) if (fa[f]) if (get(now)==get(f)) rotate(f); else rotate(now); root=now; } void insert(int v) { if (!root) {sz++;son[sz][0]=son[sz][1]=fa[sz]=0;key[sz]=v;size[sz]=1;cnt[sz]=1;root=sz;return;} int now=root,f=0; while (true) { if (key[now]==v) {cnt[now]++;update(now);update(f);splay(now);break;} f=now; now=son[now][key[now]<v]; if (now==0) { sz++;son[sz][0]=son[sz][1]=0;key[sz]=v;size[sz]=1; cnt[sz]=1;fa[sz]=f;son[f][key[f]<v]=sz; update(f);splay(sz);break; } } } int find(int v) { int ans=0,now=root; while (true) { if (v<key[now]) now=son[now][0]; else { if (son[now][0]) ans+=size[son[now][0]]; if (v==key[now]) {splay(now); return ans+1;} ans+=cnt[now]; now=son[now][1]; } } } int findkth(int x) { int now=root; while (true) { if (son[now][0] && x<=size[son[now][0]]) now=son[now][0]; else { int temp; if (son[now][0]) temp=size[son[now][0]]+cnt[now]; else temp=cnt[now]; if (x<=temp) return key[now]; x-=temp; now=son[now][1]; } } } int prev() { int now=son[root][0]; while (son[now][1]) now=son[now][1]; return now; } int succ() { int now=son[root][1]; while (son[now][0]) now=son[now][0]; return now; } bool remove(int now) { if (find(now)==-1) return false; if (cnt[root]>1) {cnt[root]--; return true;}; if (!son[root][0] && !son[root][1]) {clear(root); root=0; return true;} if (!son[root][0]) { int oldroot=root; root=son[root][1]; fa[root]=0; clear(oldroot); return true; } else if (!son[root][1]) { int oldroot=root; root=son[root][0]; fa[root]=0; clear(oldroot); return true; } int leftbig=prev(),oldroot=root; splay(leftbig); fa[son[oldroot][1]]=root; son[root][1]=son[oldroot][1]; clear(oldroot); update(root); return true; } int main() { n=read(); for (int i=1; i<=n; i++) { int opt=read(),x=read(); switch (opt) { case 1: insert(x);break; case 2: remove(x);break; case 3: printf("%d\n",find(x));break; case 4: printf("%d\n",findkth(x));break; case 5: insert(x); printf("%d\n",key[prev()]); remove(x);break; case 6: insert(x); printf("%d\n",key[succ()]); remove(x);break; } } return 0; }
相关文章推荐
- C语言查找字符串在文件中的第几行第几列
- 实现activity变暗的效果
- Android 百分比布局库(percent-support-lib) 解析与扩展
- Hbase的HMaster启动失败
- Xcode7.2与iOS9之坑 (持续更新)
- java 为什么使用工厂方法设计模式
- XRecyclerView的使用&ListView|XRecyclerView有header时Position不对问题
- 配置tomcat节点启动
- 事件拦截和分发demo
- Unity3D
- 夺命雷公狗---DEDECMS----23dedecms修改内容页面展示的信息
- 深度相机的仿激光数据创建地图--24
- js获取节点
- 浪涌防护器件的应用
- Android摇一摇(传感器之他用)
- ios8 UITableView设置 setSeparatorInset:UIEdgeInsetsZero不起作用的解决办法
- 梯度与微分
- 收集android上开源的酷炫的交互动画和视觉效果:Interactive-animation
- ORACLE ADF11g : VO绑定式查询
- cocos2d-x getVisibleSize、getContentSize、getWinSize函数