[BZOJ 4923][Lydsy1706月赛]K小值查询

传送门

势能分析平衡树,splay或treap都可以

放个指针版的就跑

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 #define rep(i,a,b) for(int i=a;i<=b;++i)
 4 const int maxn=100010;
 5 template <class T> inline bool check_Max(T &x, const T&y) { return x<y?x=y,false:true;}
 6 template <class T> inline bool check_Min(T &x, const T&y) { return x>y?x=y,false:true;}
 7 inline int gi() {
 8     int x=0; char o; bool f=true; for(;!isdigit(o=getchar());) if(o=='-') f=false;
 9     for(;isdigit(o);o=getchar()) x=(x<<1)+(x<<3)+(o&15); return f?x:~x+1;
10 }
11 struct node {int v,ky,sz,lz; node *ls,*rs;}*rt,*nul,pool[maxn],*pis=pool;
12 inline void init() { nul=pis; nul->ls=nul->rs=nul; nul->lz=nul->sz=0; rt=nul;}
13 node *newnode(int vl) { node *k=++pis; k->ls=k->rs=nul; k->v=vl; k->ky=rand(); k->lz=0; k->sz=1; return k;}
14 inline void add(node *&x,int vl) { x->v+=vl; x->lz+=vl; return ;}
15 inline void pd(node *&x) {
16     if(x->lz) {if(x->ls!=nul) add(x->ls,x->lz); if(x->rs!=nul) add(x->rs,x->lz);}x->lz=0;
17 }
18 inline void up(node *&x) { x->sz=x->ls->sz+x->rs->sz+1; }
19 inline void mrg(node *&c,node *x,node *y) {
20     if(x==nul||y==nul) {c=x==nul?y:x; return;}
21     pd(x); pd(y);
22     if(x->ky < y->ky) c=x,mrg(c->rs,x->rs,y);
23     else c=y,mrg(c->ls,x,y->ls); up(c);
24 }
25 inline void spl(node *c,node *&x,node *&y,int rk) {
26     if(c==nul) { x=y=nul; return;}
27     pd(c);
28     if(c->v <= rk) x=c,spl(c->rs,x->rs,y,rk);
29     else y=c,spl(c->ls,x,y->ls,rk); up(c);
30 }
31 inline void insert(int vl) {
32     node *x,*y; spl(rt,x,y,vl); 
33     mrg(x,x,newnode(vl)); mrg(rt,x,y);
34 }
35 int find(node *&x,int rk) {
36     if(x->ls->sz+1==rk) return x->v;
37     pd(x);
38     if(rk<=x->ls->sz) return find(x->ls,rk);
39     return find(x->rs,rk-x->ls->sz-1);
40 }
41 inline void rec(node *&now,node *&x,int vl) {
42     if(x==nul) return; pd(x); rec(now,x->ls,vl); rec(now,x->rs,vl);
43     x->ls=x->rs=nul; x->sz=1; x->v-=vl;
44     node *x1,*y1; spl(now,x1,y1,x->v); mrg(x1,x1,x); mrg(now,x1,y1);
45 }
46 inline void cg(int k) {
47     node *x,*y,*z; spl(rt,x,y,k); spl(y,y,z,k<<1);
48     add(z,-k); rec(x,y,k); mrg(rt,x,z);
49 }
50 int n,m;
51 int main() {
52 #ifndef ONLINE_JUDGE
53     freopen("3.in","r",stdin);
54     freopen("a.out","w",stdout);
55 #endif
56     n=gi();m=gi();
57     init();
58     rep(i,1,n) insert(gi());
59     rep(i,1,m) {
60         int opt=gi(),K=gi();
61         if(opt==1) printf("%d\n",find(rt,K));
62         else cg(K);
63     }
64     return 0;
65 }

 

转载于:https://www.cnblogs.com/miecoku/p/9774228.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值