老师用的是静态数组的写法,开了很多数组…

其实个人更倾向于 struct 或者用 class 封装起来。

但是鉴于太难打 好吧,是我懒得打。

然后就借鉴了老师的模板,写出了属于自己的 压行 风格。

代码见下:(注:题目是洛谷P3835

#include<cstdio>
#include<cstdlib> #define rep(i,__l,__r) for(int i=__l,i##_end_=__r;i<=i##_end_;++i)
#define fep(i,__l,__r) for(int i=__l,i##_end_=__r;i>=i##_end_;--i)
#define writc(a,b) fwrit(a),putchar(b)
#define mp(a,b) make_pair(a,b)
#define ft first
#define sd second
#define LL long long
#define ull unsigned long long
#define pii pair<int,int>
#define Endl putchar('\n')
// #define FILEOI #ifdef FILEOI
#define MAXBUFFERSIZE 500000
inline char fgetc(){
static char buf[MAXBUFFERSIZE+5],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,MAXBUFFERSIZE,stdin),p1==p2)?EOF:*p1++;
}
#undef MAXBUFFERSIZE
#define cg (c=fgetc())
#else
#define cg (c=getchar())
#endif
template<class T>inline void qread(T& x){
char c;bool f=0;
while(cg<'0'||'9'<c)f|=(c=='-');
for(x=(c^48);'0'<=cg&&c<='9';x=(x<<1)+(x<<3)+(c^48));
if(f)x=-x;
}
inline int qread(){
int x=0;char c;bool f=0;
while(cg<'0'||'9'<c)f|=(c=='-');
for(x=(c^48);'0'<=cg&&c<='9';x=(x<<1)+(x<<3)+(c^48));
return f?-x:x;
}
template<class T,class... Args>inline void qread(T& x,Args&... args){qread(x),qread(args...);}
template<class T>inline T Max(const T x,const T y){return x>y?x:y;}
template<class T>inline T Min(const T x,const T y){return x<y?x:y;}
template<class T>inline T fab(const T x){return x>0?x:-x;}
inline int gcd(const int a,const int b){return b?gcd(b,a%b):a;}
inline void getInv(int inv[],const int lim,const int MOD){
inv[0]=inv[1]=1;for(int i=2;i<=lim;++i)inv[i]=1ll*inv[MOD%i]*(MOD-MOD/i)%MOD;
}
template<class T>void fwrit(const T x){
if(x<0)return (void)(putchar('-'),fwrit(-x));
if(x>9)fwrit(x/10);putchar(x%10^48);
}
inline LL mulMod(const LL a,const LL b,const LL mod){//long long multiplie_mod
return ((a*b-(LL)((long double)a/mod*b+1e-8)*mod)%mod+mod)%mod;
} const int MAXN=5e7;
const int INF=(1ll<<31)-1; int ncnt;
int son[MAXN+5][2];
int keyof[MAXN+5];
int rd[MAXN+5];
int siz[MAXN+5];
int rt[MAXN+5];
int rcnt;
inline void pushup(const int p){
siz[p]=siz[son[p][0]]+siz[son[p][1]]+1;
}
inline int newnode(const int key){
++ncnt;
son[ncnt][0]=son[ncnt][1]=0;
keyof[ncnt]=key;
rd[ncnt]=rand();
siz[ncnt]=1;
return ncnt;
} struct Pair{
int ele[2];
Pair(){ele[0]=ele[1]=0;}
Pair(const int A,const int B){ele[0]=A,ele[1]=B;}
}; inline int cpyNode(const int p){
++ncnt;
son[ncnt][0]=son[p][0];
son[ncnt][1]=son[p][1];
keyof[ncnt]=keyof[p];
rd[ncnt]=rd[p];
siz[ncnt]=siz[p];
return ncnt;
} Pair split(int p,const int key,const bool mode,const bool flg=0){
//mode=0 时为按 key 分裂
//mode=1 时为按 rank 分裂
Pair ret=Pair(0,0);
if(p){
int d;
if(!flg)p=cpyNode(p);
if(mode)d=(siz[son[p][0]]+1<=key);
else d=(keyof[p]<=key);
if(mode && d)ret=split(son[p][d],key-siz[son[p][0]]-1,mode,flg);
else ret=split(son[p][d],key,mode,flg);
son[p][d]=ret.ele[d^1];
pushup(p);
ret.ele[d^1]=p;
}
return ret;
}
int unite(int r1,int r2,const bool flg=0){
if(r1*r2==0)return r1|r2;
if(rd[r1]<rd[r2]){
if(!flg)r1=cpyNode(r1);
son[r1][1]=unite(son[r1][1],r2,flg);
return pushup(r1),r1;
}
else{
if(!flg)r2=cpyNode(r2);
son[r2][0]=unite(r1,son[r2][0],flg);
return pushup(r2),r2;
}
} int inser(const int p,const int key){
Pair tmp=split(p,key,0);
return unite(unite(tmp.ele[0],newnode(key)),tmp.ele[1]);
} int delet(const int p,const int key){
Pair tmp0=split(p,key,0);
Pair tmp1=split(tmp0.ele[0],key-1,0);
return unite(tmp1.ele[0],tmp0.ele[1]);
} int getRank(const int p,const int key){
if(!p)return 1;
if(keyof[p]>key)return getRank(son[p][0],key);
if(keyof[p]<key)return siz[son[p][0]]+1+getRank(son[p][1],key);
return siz[son[p][0]]+1;
} int atRank(const int p,const int rk){
if(!p)return -INF;
if(siz[son[p][0]]>=rk)return atRank(son[p][0],rk);
else if(siz[son[p][0]]+1<rk)return atRank(son[p][1],rk-siz[son[p][0]]-1);
else return keyof[p];
} int getPre(const int p,const int key){
Pair tmp1=split(p,key-1,0,1);
int tsiz=siz[tmp1.ele[0]]-1;
Pair tmp0=split(tmp1.ele[0],tsiz,1,1);
int ret=keyof[tmp0.ele[1]];
tmp1.ele[0]=unite(tmp0.ele[0],tmp0.ele[1],1);
unite(tmp1.ele[0],tmp1.ele[1],1);
return ret;
} int getSuf(const int p,const int key){
Pair tmp0=split(p,key,0,1);
Pair tmp1=split(tmp0.ele[1],1,1,1);
int ret=keyof[tmp1.ele[0]];
tmp0.ele[1]=unite(tmp1.ele[0],tmp1.ele[1],1);
unite(tmp0.ele[0],tmp0.ele[1],1);
return ret;
} int N,v,opt,x; signed main(){
#ifdef FILEOI
freopen("file.in","r",stdin);
freopen("file.out","w",stdout);
#endif
srand(233);
qread(N);
rt[0]=inser(rt[0],-INF);
rt[0]=inser(rt[0],INF);
while(N--){
qread(v,opt,x);
rt[++rcnt]=rt[v];
if(opt==1)rt[rcnt]=inser(rt[rcnt],x);
else if(opt==2)rt[rcnt]=delet(rt[rcnt],x);
else if(opt==3)writc(getRank(rt[rcnt],x)-1,'\n');
else if(opt==4)writc(atRank(rt[rcnt],x+1),'\n');
else if(opt==5)writc(getPre(rt[rcnt],x),'\n');
else writc(getSuf(rt[rcnt],x),'\n');
}
return 0;
}

「模板」可持久化 HFQ-Treap的更多相关文章

  1. 「洛谷 P3834」「模板」可持久化线段树 题解报告

    题目描述 给定n个整数构成的序列,将对于指定的闭区间查询其区间内的第k小值. 输入输出格式 输入格式 第一行包含两个正整数n,m,分别表示序列的长度和查询的个数. 第二行包含n个整数,表示这个序列各项 ...

  2. 「模板」 FHQ_Treap

    「模板」 FHQ_Treap 我也是偶然发现我还没发过FHQ_Treap的板子. 那就发一波吧. 这个速度实在不算快,但是不用旋转,并且好写. 更重要的是,Splay 可以做的事情它都可以做!比如区间 ...

  3. 「模板」 FHQ_Treap 区间翻转

    「模板」 FHQ_Treap 区间翻转 没有旋转的 Treap 实现区间操作的功能,很好理解,也很好写,只是速度不算太快. 对于要翻转的区间,把整棵 Treap(存有区间 \([1,n]\) 的信息) ...

  4. 「模板」 线段树——区间乘 && 区间加 && 区间求和

    「模板」 线段树--区间乘 && 区间加 && 区间求和 原来的代码太恶心了,重贴一遍. #include <cstdio> int n,m; long l ...

  5. 「模板」 树链剖分 HLD

    「模板」 树链剖分 HLD 不懂OOP的OIer乱用OOP出人命了. 谨此纪念人生第一次类套类. 以及第一次OI相关代码打过200行. #include <algorithm> #incl ...

  6. 「模板」「讲解」Treap名次树

    Treap实现名次树 前言 学平衡树的过程可以说是相当艰难.浏览Blog的过程中看到大量指针版平衡树,不擅长指针操作的我已经接近崩溃.于是,我想着一定要写一篇非指针实现的Treap的Blog. 具体如 ...

  7. 「模板」Splay

    代码说明 对于一些变量进行说明: 变量名 说明 rt 树根 ff[u] 点 \(u\) 的父节点,特别地, ff[rt]=0 ch[u][0|1] 点 \(u\) 的 左/右儿子 siz[u] 点 \ ...

  8. 「模板」AC自动机

    目录 说明 普通版本 询问更改版 拓扑优化版本 说明 这篇博客只挂模板,具体分析请膜拜大佬 hyfhaha 大佬. 普通版本 题目传送门 #include<cstdio> #include ...

  9. Solution -「LOJ #138」「模板」类欧几里得算法

    \(\mathcal{Description}\)   Link.   \(T\) 组询问,每次给出 \(n,a,b,c,k_1,k_2\),求 \[\sum_{x=0}^nx^{k_1}\left\ ...

随机推荐

  1. 推荐几个c/c++语言编写的游戏源码下载网站

    在游戏开发的学习或工作中,利用完好的游戏源码可以事半功倍,不仅可以逆向学习开拓思维,也可以大大减少设计周期.自己浏览了很游戏源码下载的网站,发现大多数质量都良莠不齐,且大部分需要消费才能下载,下面整理 ...

  2. 【Hibernate 懒加载】debug模式懒加载获取空数据

    <many-to-one name="department" class="k.domain.Department" column="depar ...

  3. 数据库程序接口——JDBC——功能第二篇——数据源之C3P0数据源

    综述 C3P0由三部分内容组成.实例化对象,各配置项的含义,以及加载配置项的方式. 实例化对象的方式有三种,第一种方式直接new ComboPooledDataSource,第二种方式使用工厂类Dat ...

  4. 读懂timing report

    三部分:表头/launch path /capture path 1.表头 1) 工具版本信息:如示例中的18.10-p001,对某个具体项目timing signoff 工具的版本最好保证一致: 操 ...

  5. 根据IP地址查找MAC地址

    ping 地址 arp -a得到ip对应的mac

  6. 一个简单的python爬虫,爬取知乎

    一个简单的python爬虫,爬取知乎 主要实现 爬取一个收藏夹 里 所有问题答案下的 图片 文字信息暂未收录,可自行实现,比图片更简单 具体代码里有详细注释,请自行阅读 项目源码: # -*- cod ...

  7. December 31st, Week 53rd Tuesday, 2019

    Nothing comes from nothing. 天下没有免费的午餐. Nothing comes from nothing, and in some cases, even something ...

  8. Spring Boot 如何动态切换数据源

    本章是一个完整的 Spring Boot 动态数据源切换示例,例如主数据库使用 lionsea 从数据库 lionsea_slave1.lionsea_slave2.只需要在对应的代码上使用 Data ...

  9. WLC license管理

    关于控制器的license,可以参考对应平台的Datasheet: Cisco 2504 WLC Cisco 3504 WLC Cisco 5508 WLC Cisco 5520 WLC Cisco ...

  10. 【PAT甲级】1090 Highest Price in Supply Chain (25 分)

    题意: 输入一个正整数N(<=1e5),和两个小数r和f,表示树的结点总数和商品的原价以及每向下一层价格升高的幅度.下一行输入N个结点的父结点,-1表示为根节点.输出最深的叶子结点处购买商品的价 ...