[BZOJ4923][Lydsy六月份月赛 .G][平衡树]K小值查询
来源:互联网 发布:丽水学院网络教学平台 编辑:程序博客网 时间:2024/06/06 07:34
直接上题解
学了发非旋转Treap,感觉常数有点大
#include <cstdio>#include <iostream>#include <algorithm>using namespace std;const int N=100010;int n,m;int a[N];struct node{ node *l,*r; int val,fix,size,minus; node(){ } node(int x):val(x),fix(rand()),size(1),l(NULL),r(NULL),minus(0){} void Push(){ if(!minus) return ; if(l) l->val-=minus,l->minus+=minus; if(r) r->val-=minus,r->minus+=minus; minus=0; } void Up(){ size=(l?l->size:0)+(r?r->size:0)+1; } int mark(int x){ val-=x; minus+=x; }}poor[N],*rt;inline char nc(){ static char buf[100000],*p1=buf,*p2=buf; return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;}inline void rea(int &x){ char c=nc(); x=0; for(;c>'9'||c<'0';c=nc());for(;c>='0'&&c<='9';x=x*10+c-'0',c=nc());}inline int Size(node *x){ return x?x->size:0;}typedef pair<node*,node*> Droot;inline node *newnode(int x,int p){ poor[p].val=x; poor[p].fix=rand(); poor[p].size=1; return poor+p;}inline node *Merge(node *x,node *y){ if(!x||!y) return !x?y:x; x->Push(); y->Push(); if(x->fix<y->fix){ x->r=Merge(x->r,y); x->Up(); return x; } else{ y->l=Merge(x,y->l); y->Up(); return y; }}inline node *Query(int k){ node *x=rt; while(x){ x->Push(); if(k==Size(x->l)+1) return x; if(k>Size(x->l)) k-=Size(x->l)+1,x=x->r; else x=x->l; } return 0;}inline int Rank(int k){ node *x=rt; int ret=0; while(x){ x->Push(); if(x->val<k) ret+=Size(x->l)+1,x=x->r; else x=x->l; } return ret+1;}Droot Split(node *x,int k){ if(!x) return Droot(NULL,NULL); x->Push(); if(k<=Size(x->l)){ Droot ret=Split(x->l,k); x->l=ret.second; x->Up(); ret.second=x; return ret; } else{ Droot ret=Split(x->r,k-Size(x->l)-1); x->r=ret.first; x->Up(); ret.first=x; return ret; }}bool Modify(int k){ int cur=Rank(k+1); node *p=Query(cur); if(!p||p->val>2*k) return false; Droot x=Split(rt,cur-1); Droot y=Split(x.second,1); y.first->val-=k; rt=Merge(x.first,y.second); cur=Rank(y.first->val); x=Split(rt,cur-1); rt=Merge(x.first,Merge(y.first,x.second)); return true;}int opt,k;int main(){ rea(n); rea(m); for(int i=1;i<=n;i++) rea(a[i]); sort(a+1,a+1+n); for(int i=1;i<=n;i++) poor[i]=node(a[i]),rt=Merge(rt,poor+i); while(m--){ rea(opt); rea(k); if(opt==1) printf("%d\n",Query(k)->val); else{ while(Modify(k)); int cur; if((cur=Rank(k+1))<=n){ Droot x=Split(rt,cur-1); x.second->mark(k); rt=Merge(x.first,x.second); } } } return 0;}
阅读全文
0 0
- [BZOJ4923][Lydsy六月份月赛 .G][平衡树]K小值查询
- [BZOJ4917][Lydsy六月份月赛 .A][模拟]Hash Killer IV
- [BZOJ4920][Lydsy六月份月赛 .D][数学][三分]薄饼切割
- [BZOJ4921][Lydsy六月份月赛 .E][二分][瞎搞]互质序列
- [BZOJ4919][Lydsy六月份月赛 .C][树上DP][启发式合并]大根堆
- Lydsy八月份月赛
- bzoj 5072: [Lydsy十月月赛]小A的树 树形dp
- BZOJ5072[Lydsy十月月赛] 小A的树 解题报告【树上背包/树形DP】
- BZOJ 5072: [Lydsy十月月赛]小A的树 树形dp
- 【乱搞】BZOJ5074 [Lydsy十月月赛]小B的数字
- 【bzoj5074】 [Lydsy十月月赛]小B的数字
- [BZOJ]5074: [Lydsy十月月赛]小B的数字
- bzoj5071: [Lydsy十月月赛]小A的数字
- bzoj 5071: [Lydsy十月月赛]小A的数字
- bzoj5071 [Lydsy十月月赛]小A的数字
- bzoj5074 [Lydsy十月月赛]小B的数字
- bzoj 5071: [Lydsy十月月赛]小A的数字
- bzoj 5074: [Lydsy十月月赛]小B的数字
- 【数据库】mysql 常用命令(一)
- 自定义控件的属性
- laravel 的 intervention-image 图像处理笔记
- JS面向对象---继承
- BMI计算
- [BZOJ4923][Lydsy六月份月赛 .G][平衡树]K小值查询
- openssl移植
- 2017.6.29 学习记录 MySql的运用查询
- 【陷阱代码】c++ 第一篇 简单但却常见
- Spring的bean后处理器和容器后处理器
- window对象
- MeritMS—利用beego实现数据库自动备份
- 浅谈JavaScript之BOM
- js面向对象的继承实例-call