HYSBZ 3196Tyvj 1730 二逼平衡树(树套树)

来源:互联网 发布:淘宝贝亲奶瓶正品 编辑:程序博客网 时间:2024/05/21 11:17

bzoj能过.tyvj有两组TLE了.以后写分块看能不能过

#include <bits/stdc++.h>#include <iostream>#include <cstdio>#include <cmath>#include <cstring>#include <algorithm>using namespace std;#define LL long long #define pii pair<int, int>#define MP make_pair#define ls i << 1#define rs ls | 1#define md (ll + rr >> 1)#define lson ll, md, ls#define rson md + 1, rr, rs#define inf 0x3f3f3f3f#define mod 1000000007#define N 50010#define M 400020char buf[16000000],*pt = buf,*o = buf;int getint(){    int f = 1,x = 0;    while((*pt != '-') && (*pt < '0' || *pt > '9'))    pt ++;    if(*pt == '-')    f = -1,pt ++;    else    x = *pt++ - 48;    while(*pt >= '0' && *pt <= '9')    x = x * 10 + *pt ++ - 48;    return x * f;}char getch(){    char ch;    while(*pt < 'A' || *pt > 'Z')    pt ++;    ch=*pt;pt++;    return ch;}int ch[N*30][2];  int rand_val[N*30], key[N*30], sz[N*30], cnt[N*30];  int tot, rt[N<<2], a[N];int creat(int val) {      ++tot;      ch[tot][0] = ch[tot][1] = 0;      rand_val[tot] = rand();      key[tot] = val;      sz[tot] = cnt[tot] = 1;      return tot;  }int cmp(int x, int val) {      if(key[x] == val) return -1;      return val < key[x]? 0: 1;  }void push_up(int x) {      sz[x] = cnt[x] + sz[ch[x][0]] + sz[ch[x][1]];  }  void rot(int &x, int d) {      int k = ch[x][d^1];      ch[x][d^1] = ch[k][d];      ch[k][d] = x;      push_up(x);      push_up(k);      x = k;  }  void insert(int &x, int val) {      if(x == 0) {          x = creat(val);          return;      }      int d = cmp(x, val);      if(d == -1) {          cnt[x]++, sz[x]++;          return;      }      insert(ch[x][d], val);      if(rand_val[ch[x][d]] > rand_val[x]) rot(x, d ^ 1);      push_up(x);  }  void del(int &x, int val) {      if(x == 0) return;      int d = cmp(x, val);      if(d == -1) {          if(cnt[x] > 1) {              cnt[x]--, sz[x]--;              return;          }          if(!ch[x][0]) x = ch[x][1];          else if(!ch[x][1]) x = ch[x][0];          else {              int d2 = rand_val[ch[x][0]] > rand_val[ch[x][1]]? 1: 0;              rot(x, d2);              del(ch[x][d2], val);          }      }      else del(ch[x][d], val);      if(x) push_up(x);  } int kth(int x, int val){    if(!x) return 0;    int d = cmp(x, val);    if(d == -1)        return sz[ch[x][0]] + cnt[x];    if(d == 0)        return kth(ch[x][0], val);    return sz[ch[x][0]] + cnt[x] + kth(ch[x][1], val);}int find_pre(int x, int val){    if(!x) return -inf;    int d = cmp(x, val);    if(d == 1)        return max(key[x], find_pre(ch[x][1], val));    return find_pre(ch[x][0], val);}int find_suf(int x, int val){    if(!x) return inf;    int d = cmp(x, val);    if(d == 0)        return min(key[x], find_suf(ch[x][0], val));    return find_suf(ch[x][1], val);}void build(int ll, int rr, int i){    rt[i] = 0;    for(int j = ll; j <= rr; ++j)        insert(rt[i], a[j]);    if(ll == rr) return ;    build(lson);    build(rson);}void update(int x, int pre, int cur, int ll, int rr, int i){    del(rt[i], pre);    insert(rt[i], cur);    if(ll == rr) return ;    if(x <= md) update(x, pre, cur, lson);    else update(x, pre, cur, rson);}int query_1(int l, int r, int v, int ll, int rr, int i){    if(l <= ll && r >= rr)        return kth(rt[i], v);    if(r <= md) return query_1(l, r, v, lson);    else if(l > md) return query_1(l, r, v, rson);    else return query_1(l, md, v, lson) + query_1(md + 1, r, v, rson);}int query_4(int l, int r, int v, int ll, int rr, int i){    if(l <= ll && r >= rr)        return find_pre(rt[i], v);    if(r <= md) return query_4(l, r, v, lson);    else if(l > md) return query_4(l, r, v, rson);    else return max(query_4(l, md, v, lson), query_4(md + 1, r, v, rson));}int query_5(int l, int r, int v, int ll, int rr, int i){    if(l <= ll && r >= rr)        return find_suf(rt[i], v);    if(r <= md) return query_5(l, r, v, lson);    else if(l > md) return query_5(l, r, v, rson);    else return min(query_5(l, md, v, lson), query_5(md + 1, r, v, rson));}int main(){    //freopen("tt.txt", "r", stdin);    fread(buf, 1, 16000000, stdin);    int n, m;    n = getint(), m = getint();    for(int i = 1; i <= n; ++i)        a[i] = getint();    tot = 0;    build(1, n, 1);    while(m--){        int op, l, r, k;        op = getint();        if(op == 3){            l = getint(), k = getint();            update(l, a[l], k, 1, n, 1);            a[l] = k;            continue;        }        l = getint(), r = getint(), k = getint();        if(op == 1)            printf("%d\n", query_1(l, r, k - 1, 1, n, 1) + 1);        else if(op == 2){            int L = 0, R = inf;            while(L < R){                int mid = (L + R) >> 1;                if(query_1(l, r, mid, 1, n, 1) >= k)                    R = mid;                else L = mid + 1;            }            printf("%d\n", L);        }        else if(op == 4)            printf("%d\n", query_4(l, r, k, 1, n, 1));        else printf("%d\n", query_5(l, r, k, 1, n, 1));    }           return 0;}
0 0