您的位置:首页 > 其它

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

2016-04-04 13:42 260 查看
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 400020

char 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
;
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: