博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
NOIP的基本模板进阶
阅读量:5100 次
发布时间:2019-06-13

本文共 3509 字,大约阅读时间需要 11 分钟。

        NOIP基本模板进阶


一.Treap

支持:

  1. 插入x
  2. 删除x(若有多个相同的数,因只删除一个)
  3. 查询x的排名(排名定义为比当前数小的数的个数+1。若有多个相同的数,因输出最小的排名)
  4. 查询排名为x的数
  5. x的前驱(前驱定义为小于x,且最大的数)
  6. x的后继(后继定义为大于x,且最小的数)
#include
#include
#include
#include
#include
#include
#include
using namespace std;#define INF 0x7fffffff#define N 100010int n,tot,root;struct Treap{ int l,r,val,len,cnt,siz;}a[N];int New(int x){ a[++tot].val=x; a[tot].len=rand(); a[tot].cnt=a[tot].siz=1; return tot;}void Update(int p){ a[p].siz=a[a[p].l].siz+a[a[p].r].siz+a[p].cnt;}void Build(){ New(-INF); New(INF); root=1; a[1].r=2; Update(root);}int GetRankByVal(int p,int k){ if(p==0) return 0; if(k==a[p].val) return a[a[p].l].siz+1; else if(k
=rank) return GetValByRank(a[p].l,rank); else if(a[a[p].l].siz+a[p].cnt>=rank) return a[p].val; else return GetValByRank(a[p].r,rank-a[a[p].l].siz-a[p].cnt);}void zig(int &p){ int q=a[p].l; a[p].l=a[q].r; a[q].r=p; p=q; Update(a[p].r); Update(p);}void zag(int &p){ int q=a[p].r; a[p].r=a[q].l; a[q].l=p; p=q; Update(a[p].l); Update(p);}void Insert(int &p,int k){ if(p==0) { p=New(k); return; } if(k==a[p].val) { a[p].cnt++; Update(p); return; } if(k
1) { a[p].cnt--; Update(p); return; } if(a[p].l||a[p].r) { if(a[p].r==0||a[a[p].l].len>a[a[p].r].len) { zig(p); Remove(a[p].r,k); } else { zag(p); Remove(a[p].l,k); } Update(p); } else p=0; return; } if(k
0) { p=a[p].l; while(a[p].r>0) p=a[p].r; ans=p; } break; } if(a[p].val
a[ans].val) ans=p; if(k
0) { p=a[p].r; while(a[p].l>0) p=a[p].l; ans=p; } break; } if(a[p].val>k&&a[p].val

二.非旋转Treap

支持普通Treap操作,区间翻转

#include
#include
#include
#include
#include
#include
using namespace std;#define N 100010int n,tot,root,m;bool flag[N];struct Treap{ int val,len,siz,ch[2]; void clear() { ch[0]=ch[1]=siz=val=len=0; }}t[N];void update(int p){ t[p].siz=t[t[p].ch[0]].siz+t[t[p].ch[1]].siz+1;}void pushdown(int p){ if(!flag[p]) return; swap(t[p].ch[0],t[p].ch[1]); if(t[p].ch[0]!=0) flag[t[p].ch[0]]^=1; if(t[p].ch[1]!=0) flag[t[p].ch[1]]^=1; flag[p]=0;}int merge(int x,int y){ if(!x||!y) return x+y; pushdown(x); pushdown(y); if(t[x].len

 三.权值线段树

#include
#include
#include
#include
#include
using namespace std;#define N 200010int m,n,idx,a[N],b[N],cnt[N<<2],u[N],idxx=1;void pushup(int p){ cnt[p]=cnt[p<<1]+cnt[p<<1|1];}void update(int l,int r,int k,int v){ if(l==r) { cnt[k]++; return; } int mid=(l+r)>>1; if(v<=mid) update(l,mid,k<<1,v); if(v>mid) update(mid+1,r,k<<1|1,v); pushup(k);}int query(int l,int r,int k,int rank){ if(l==r) return l; int mid=(l+r)>>1; if(rank<=cnt[k<<1]) return query(l,mid,k<<1,rank); else return query(mid+1,r,k<<1|1,rank-cnt[k<<1]);}int main(){ scanf("%d%d",&m,&n); for(int i=1;i<=m;i++) { scanf("%d",&a[i]); b[i]=a[i]; } for(int i=1;i<=n;i++) scanf("%d",&u[i]); sort(b+1,b+m+1); int tot=unique(b+1,b+m+1)-b-1; for(int i=1;i<=m;i++) { int x=lower_bound(b+1,b+tot+1,a[i])-b; update(1,tot,1,x); while(i==u[idxx]) { printf("%d\n",b[query(1,tot,1,++idx)]); ++idxx; } } return 0;}

 

转载于:https://www.cnblogs.com/jiangminghong/p/10049940.html

你可能感兴趣的文章
printcap - 打印机相容性数据库
查看>>
LINUX超级用户(权限)在系统管理中的作用
查看>>
iOS动画(一)coreAnimation 教程(转)
查看>>
Github 如何上传本地文件
查看>>
dos命令操作一 基本篇
查看>>
element对象
查看>>
Android SQLite (一) 数据库简介
查看>>
HashMap和HashSet的区别
查看>>
python-2:基础点滴 字符串函数之一 str
查看>>
ASP.NET MVC 5 入门教程 (1) 新建项目
查看>>
MySQL复习1
查看>>
线程、线程ID获取
查看>>
Mysql 中的事件 事件调度器(Event Scheduler)
查看>>
安装XAMPP时出现 unable to realloc 83886080 bytes
查看>>
ZJOI2007 矩阵游戏
查看>>
为什么用多个域名来存储网站资源会更有效
查看>>
基于RStudio 实现数据可视化之二
查看>>
redis面试总结
查看>>
Apache Oozie Coordinator 作业自定义配置定时任务
查看>>
c语言与数据结构(线性表之顺序表的学习)
查看>>