P2234 P1486 P3224 -无旋Treap

acwing265 P2234 营业额统计

#include<bits/stdc++.h>
using namespace std;
const int maxn = 4e4;

struct node{
    int key, val;
    int l, r;
}fhq[maxn];
int cnt, root;

mt19937 rnd(233);

int newnode(int val){
    cnt++;
    fhq[cnt].key = rnd();
    fhq[cnt].val = val;
    fhq[cnt].l = fhq[cnt].r = 0;
    return cnt;
}

void split(int now, int val, int &x, int &y){
    if(!now) x = y = 0;
    else{
        if(fhq[now].val > val){
            y = now;
            split(fhq[now].l, val, x, fhq[now].l);
        }else{
            x = now;
            split(fhq[now].r, val, fhq[now].r, y);
        }
    }
}

int merge(int x, int y){
    if(!x || !y) return x+y;
    else{
        if(fhq[x].key < fhq[y].key){
            fhq[x].r = merge(fhq[x].r, y);
            return x;
        }else{
            fhq[y].l = merge(x, fhq[y].l);
            return y;
        }
    }
}

int x, y, z1, z2, tmp1, tmp2;

void insert(int val){
    split(root, val, x, y);
    root = merge(merge(x, newnode(val)), y);
}

int ans;
void getans(int val){
    split(root, val, x, y);
    z1 = x;
    z2 = y;
    if(z1 && z2){
        while(z1){
            tmp2 = fhq[z1].val;
            z1 = fhq[z1].r;
        }
        while(z2){
            tmp1 = fhq[z2].val;
            z2 = fhq[z2].l;
        }
        ans += min(abs(val - tmp1), abs(val - tmp2));
        //cout<<"**"<<min(abs(val - tmp1), abs(val - tmp2))<<endl;
    }else if(!z1){ 
        while(z2){
            tmp1 = fhq[z2].val;
            z2 = fhq[z2].l;
            //cout<<"debug"<<tmp1<<endl;
        }
        ans += abs(val - tmp1);
        //cout<<"*"<<abs(val - tmp1)<<endl;
    }
    else if(!z2){
        while(z1){
            tmp2 = fhq[z1].val;
            z1 = fhq[z1].r;
        }
        ans += abs(val - tmp2);
        //cout<<"***"<<abs(val - tmp2)<<endl;
    }
    
    root = merge(x, y);
}

int main(){
    int n, t;
    ios::sync_with_stdio(false), cin.tie(0);

    cin>>n; cin>>t; n--;
    ans += t;
    insert(t);
    while(n--){
        cin>>t;
        getans(t);
        insert(t);
    }
    cout<<ans;
    return 0;
}

acwing950 P1486 郁闷的出纳员

#include<bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 5;

struct node{
    int key, val;
    int l, r;
    int size;
    node(){
        l = r = 0;
        size = 0;
    }
}fhq[maxn];
int cnt, root;
int add, mn;

mt19937 rnd(233);

int newnode(int val){
    cnt++;
    fhq[cnt].key = rnd();
    fhq[cnt].val = val;
    fhq[cnt].l = fhq[cnt].r = 0;
    fhq[cnt].size = 1;
    return cnt;
}

inline void update(int now){
    fhq[now].size = fhq[fhq[now].l].size + fhq[fhq[now].r].size + 1;
}

void split(int now, int val, int &x, int &y){
    if(!now) x=y=0;
    else{
        if(fhq[now].val <= val){
            x = now;
            split(fhq[now].r, val, fhq[now].r, y);
        }else{
            y = now;
            split(fhq[now].l, val, x, fhq[now].l);
        }
        update(now);
    }
}

int merge(int x, int y){
    if(!x || !y) return x+y;
    else{
        if(fhq[x].key < fhq[y].key){
            fhq[x].r = merge(fhq[x].r, y);
            update(x);
            return x;
        }else{
            fhq[y].l = merge(x, fhq[y].l);
            update(y);
            return y;
        }
    }
}

int getkth(int k){
    if(k > fhq[root].size)
        return -1;
    
    int now = root;
    int rank = fhq[now].size - k + 1;
    while(now){
        if(fhq[fhq[now].l].size + 1 == rank){
            break;
        }else if(fhq[fhq[now].l].size + 1 > rank){
            now = fhq[now].l;
        }else{
            rank -= fhq[fhq[now].l].size + 1;
            now = fhq[now].r;
        }
    }
    return fhq[now].val + add;
}

int x, y, ans;
void del(int val){
    split(root, val, x, y);
    ans += fhq[x].size;
    root = y;
}

void insert(int val){
    split(root, val, x, y);
    root = merge(x, merge(newnode(val), y));
}

int main(){
    int n;
    char c[10];
    int t;

    scanf("%d%d", &n, &mn);
    while(n--){
        scanf("%s %d", c, &t);
        if(c[0] == 'I'){ 
            if(t >= mn)
                insert(t - add);
        }
        else if(c[0] == 'A') add += t;
        else if(c[0] == 'S'){ 
            add -= t;
            del(mn - add - 1);
        }
        else if(c[0] == 'F') cout<<getkth(t)<<"\n";
    }
    cout<<ans<<endl;
    return 0;
}

acwing1063 P3224 永无乡

#include<bits/stdc++.h>
#define debug() cout<<"debug\n"
using namespace std;
const int maxn = 1e5 + 5;

struct node{
    int l, r;
    int val, key;
    int size;
    node(){
        l = r = size = 0;
    }
}tree[maxn];
int cnt, root[maxn];
int w[maxn], idx[maxn];

int getf(int u){
    return u == root[u]?u:root[u] = getf(root[u]);
}

mt19937 rnd(233);
int newnode(int val){
    tree[++cnt].val = val;
    tree[cnt].key = rnd();
    tree[cnt].l = tree[cnt].r = 0;
    tree[cnt].size = 1;
    return cnt;
}

void update(int x){
    tree[x].size = tree[tree[x].l].size + tree[tree[x].r].size + 1;
}

void split(int root, int val, int &x, int &y){
    if(!root){
        x = y = 0;
        return ;
    }else{
        if(tree[root].val <= val){
            x = root;
            split(tree[root].r, val, tree[root].r, y);
        }else{
            y = root;
            split(tree[root].l, val, x, tree[root].l);
        }
        update(root);
    }
}

int merge(int x, int y){
    if(!x || !y) return x+y;
    else{
        if(tree[x].key < tree[y].key){
            tree[x].r = merge(tree[x].r, y);
            update(x);
            return x;
        }else{
            tree[y].l = merge(x, tree[y].l);
            update(y);
            return y;
        }
    }
}

int x, y;
void insert(int &root, int val){
    split(root, w[val], x, y);
    root = merge(x, merge(val, y));
    //debug();
}

void dfs(int a, int &b){
    if(!a) return;
    dfs(tree[a].l, b);
    dfs(tree[a].r, b);
    tree[a].l = tree[a].r = 0;
    //debug();
    insert(b, a);
    //debug();
}
//传结点编号
int Merge(int a, int b){
    if(tree[a].size > tree[b].size) swap(a, b);
    dfs(a, b);
    return b;
}

int kth(int root, int k){
    int now = root;
    while(1){
        if(k == tree[tree[now].l].size + 1) return now;
        else if(k < tree[tree[now].l].size + 1) now = tree[now].l;
        else{
            k -= tree[tree[now].l].size + 1;
            now = tree[now].r;
        }
    }
}

int main(){
    int n, m, Q, x, k;
    char q[2];
    scanf("%d%d", &n, &m);

    for(int i = 1; i <= n; i++){
        scanf("%d", w+i);
        root[i] = newnode(w[i]); //以结点权值建点,root[i]第i个treap根结点编号
    }

    int u, v, fa;
    while(m--){
        scanf("%d%d", &u, &v);
        if(getf(u) == getf(v)) continue;
        fa = Merge(root[u], root[v]);
        root[getf(u)] = root[getf(v)] = fa;
    }

    scanf("%d", &Q);
    while(Q--){
        scanf("%s%d%d", q, &x, &k);
        if(q[0] == 'Q'){
            if(tree[getf(x)].size < k)
                printf("-1\n");
            else
                printf("%d\n", kth(getf(x), k));
        }else if(q[0] == 'B'){
            if(getf(x) == getf(k)) continue;
            fa = Merge(root[x], root[k]);
            root[getf(x)] = root[getf(k)] = fa;
        }
    }
    return 0;
}

T1脑瘫题 求前驱后缀其实set也能做

T2求Kth 基操,注意新加入的员工插入时薪水-add即可(因为是全局增减量

T3 求Kth&启发式合并treap (刚写的时候因为弄混权值和编号卡了好久……(还把split写炸了QAQ

启发式合并:把小treap暴力拆了插到大treap里…(i了i了

posted @ 2020-11-25 10:51  IrIrIrllleaf  阅读(145)  评论(0编辑  收藏  举报