记录编号 390950 评测结果 AAAAAAAAAA
题目名称 [TYVJ1730]二逼平衡树 最终得分 100
用户昵称 Gravatarsxysxy 是否通过 通过
代码语言 C++ 运行时间 4.606 s
提交时间 2017-04-04 18:37:01 内存使用 5.33 MiB
显示代码纯文本
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <list>
#include <queue>
#include <vector>
#include <cctype>
using namespace std;
struct node{
  node *ls, *rs;
  int fix, value;
  int size;  
  node(int v){
    fix = rand(); size = 1; value = v;
    ls = rs = NULL;
  }
  inline int lsize(){
    return ls?ls->size:0;
  }
  inline int rsize(){
    return rs?rs->size:0;
  }
  inline void pushup(){
    size = 1+lsize()+rsize();
  }
};
node *merge(node *x, node *y){
  if(!x)return y; if(!y)return x;
  if(x->fix < y->fix){
    x->rs = merge(x->rs, y);
    x->pushup(); return x;
  }else{
    y->ls = merge(x, y->ls);
    y->pushup(); return y;
  }
}
typedef pair<node *, node *>droot;
droot split(node *x, int k){
  droot r(NULL, NULL);
  if(!x)return r;
  if(x->lsize() >= k){
    r = split(x->ls, k);
    x->ls = r.second;
    x->pushup();
    r.second = x;
  }else{
    r = split(x->rs, k-x->lsize()-1);
    x->rs = r.first;
    x->pushup();
    r.first = x;
  }
  return r;
}
int lower(node *x, int v){
  if(!x)return 0;
  if(v < x->value)return lower(x->ls, v);
  else return 1+x->lsize()+lower(x->rs, v);
}
node *insert(node *x, int v){
  int k = lower(x, v);
  droot p = split(x, k);
  node *d = new node(v);
  return merge(merge(p.first, d), p.second);
}
node *erase(node *x, int v){
  int k = lower(x, v);
  droot p1 = split(x, k-1);
  droot p2 = split(p1.second, 1);
  if(p2.first && p2.first->value == v){
    delete p2.first; p2.first = NULL;
  }
  return merge(p1.first, merge(p2.first, p2.second));
}
#define MAXN 50001
struct segtree{
  node *root;
  int ls, rs;
}ns[MAXN<<1+2];
int _seglast = 1;
int a[MAXN];
inline 
void build(node *&rt, int l, int r){
  for(int i = l; i <= r; i++)rt = insert(rt, a[i]);
}
int build(int l, int r){
  if(l > r)return 0;
  int c = _seglast++;
  if(l == r){
    ns[c].root = new node(a[l]);
  }else{
    build(ns[c].root, l, r);
    int m = (l+r)>>1;
    ns[c].ls = build(l, m); ns[c].rs = build(m+1, r);
  }
  return c;
}
int query(int c, int p, int l, int r, int L, int R){ // <= p
  if(!c)return 0;
  if(l <= L && R <= r)return lower(ns[c].root, p);
  else{
    int M = (L+R)>>1, ret = 0;
    if(l <= M)ret += query(ns[c].ls, p, l, r, L, M);
    if(r > M)ret += query(ns[c].rs, p, l, r, M+1, R);
    return ret;
  }
}
void update(int c, int p, int v, int L, int R){
  if(!c)return;
  ns[c].root = erase(ns[c].root, a[p]);
  ns[c].root = insert(ns[c].root, v);
  if(L == R && L == p)return;
  int M = (L+R)>>1;
  if(p <= M)update(ns[c].ls, p, v, L, M);
  else update(ns[c].rs, p, v, M+1, R);
}
int n;
inline 
int option1(int l, int r, int v){ // [l, r] rank
  return query(1, v-1, l, r, 1, n)+1;
}
int option2(int l, int r, int k){ // [l, r] kth
  int ans = 0, x = 0, y = 1e8;
  while(x <= y){
    int m = (x+y)>>1;
    if(query(1, m, l, r, 1, n) >= k){
      ans = m;
      y = m-1;
    }else x = m+1;
  }
  return ans;
}
inline 
void option3(int p, int v){ //modfity a[p] = v
  update(1, p, v, 1, n);
  a[p] = v;
}
inline 
int option4(int l, int r, int v){ //prev in [l, r] of v
  return option2(l, r, option1(l, r, v)-1); 
}
inline 
int option5(int l, int r, int v){ //succ in [l, r] of v
  return option2(l, r, option1(l, r, v+1));
}
namespace IO{
  char buf[1<<18], *fs, *ft;
  inline char getc(){
    return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<18,stdin)),fs==ft)?0:*fs++;
  }
  template<typename T>
  void splay(T &r){
    char c; bool s = false;
    while((c = getc())){
      if(c >= '0' && c <= '9'){
        r = c^0x30; break;
      }else if(c == '-')s = true;
    }while(isdigit(c = getc()))
      r = ((r+(r<<2))<<1)+(c^0x30);
    if(s)r = -r;
  }
}using IO::splay;
int main(){
//  freopen("test_data.txt", "r", stdin);
  freopen("psh.in", "r", stdin);
  freopen("psh.out", "w", stdout);
  splay(n); int m; splay(m);
  for(int i = 1; i <= n; i++)splay(a[i]);
  build(1, n);
  while(m--){
    int op; splay(op);
    int l, r, k, p;
    switch(op){
      case 1:{
        splay(l); splay(r); splay(k);
        printf("%d\n", option1(l, r, k));
      }break;
      case 2:{
        splay(l); splay(r); splay(k);
        printf("%d\n", option2(l, r, k));
      }break;
      case 3:{
        splay(p); splay(k);
        option3(p, k);
      }break;
      case 4:{
        splay(l); splay(r); splay(k);
        printf("%d\n", option4(l, r, k));
      }break;
      case 5:{
        splay(l); splay(r); splay(k);
        printf("%d\n", option5(l, r, k));
      }break;
    }
  }
  return 0;
}