2012 Asia Tianjin Regional Contest - Queue Sequence

  坑爹splay
  很裸就是了
  记录每个数正数和负数的节点编号
  insert p,先插正数,设正数前面有x个正数,然后插到第x+1个负数前面。注意有边界问题,机智的我加了个+0和-0
  query p,直接split查
  remove p,直接提前驱后继然后删
  另外要用一个可以动态维护最小值的东西来维护insert的数。
  怕被卡常,手写了个线段树。其实平板电视也不是不可以?
  有些要注意的地方。。。
  比如remove完一个节点之后要upd
  求第k个负数的姿势有一点点不同
  +0和-0处理起来有些地方也要注意一下
  hdu是I64而不是ll(不过好像用ll的时候就A掉了?)
  总共写了1h+调了0.5h的样子。
  还好吧。

#include <bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=a,_=b;i<=_;i++)
#define per(i,a,b) for(int i=a,_=b;i>=_;i--)
#define maxn 200007

inline int rd() {
    char c = getchar() ;
    while (!isdigit(c) && c != '-') c = getchar();
    int x = 0 , f = 1;
    if (c == '-') f = -1 ; else x = c - '0';
    while (isdigit(c = getchar())) x = x * 10 + c - '0';
    return x * f;
}

typedef long long ll;
typedef int arr_int[maxn];
typedef ll  arr_ll [maxn];

arr_int sz , cnt , fa , neg , pos , val;
arr_ll  sum;
int ch[maxn][2] , rt , n , tot;

struct SegTree {
    int cnt[maxn * 4 + 1] , p , tg[maxn * 4 + 1];
    #define lc (u << 1)
    #define rc (u << 1 | 1)
    #define T int u = 1 , int l = 1 , int r = n
    #define L lc , l , m
    #define R rc , m + 1 , r
    void modi(T) {
        if (l == r) {
            cnt[u] = 0;
            return ;
        }
        if (tg[u]) {
            cnt[lc] = cnt[rc] = 0;
            tg[lc] = tg[rc] = 1;
            tg[u] = 0;
        }
        int m = (l + r) >> 1;
        if (p <= m) modi(L);
        else modi(R);
        cnt[u] --;
    }
    int que(T) {
        if (l == r) return cnt[u] = 1 , l;
        if (tg[u]) {
            cnt[lc] = cnt[rc] = 0;
            tg[lc] = tg[rc] = 1;
            tg[u] = 0;
        }
        int m = (l + r) >> 1 , x;
        if (cnt[lc] < m - l + 1) x = que(L);
        else x = que(R);
        cnt[u] ++;
        return x;
    }
    inline void add(int x) {
        p = x;
        modi();
    }
    inline int get() {
        return que();
    }
    inline void clear() {
        tg[1] = 1 , cnt[1] = 0;
    }
    #undef lc
    #undef rc
    #undef T
    #undef L
    #undef R
}_num;

#define lc ch[u][0]
#define rc ch[u][1]
#define KEY ch[ch[rt][1]][0]

void dbg(int u) {
    if (lc) dbg(lc);
    printf("%d " , val[u]);
    if (rc) dbg(rc);
}

inline int newnode(int v , int f) {
    ++ tot;
    if (f > 0) pos[v] = tot;
    else neg[v] = tot;
    val[tot] = v * f;
    sum[tot] = val[tot];
    cnt[tot] = (f < 0);
    sz [tot] = 1;
    return tot;
}

inline void delnode(int u) {
    int f = fa[u];
    ch[f][ch[f][1] == u] = 0;
    fa[u] = 0;
}

inline void upd(int u) {
    sum[u] = val[u];
    cnt[u] = (val[u] <= 0 && u != 1);
    sz[u] = 1;
    if (lc) sum[u] += sum[lc] , cnt[u] += cnt[lc] , sz[u] += sz[lc];
    if (rc) sum[u] += sum[rc] , cnt[u] += cnt[rc] , sz[u] += sz[rc];
}

inline void mt() { upd(ch[rt][1]) , upd(rt) ; }

void input() {
    _num.clear();
    rep (i , 1 , tot) fa[i] = 0 , ch[i][0] = ch[i][1] = 0;
    tot = 0;
    rt = newnode(0 , 1);
    pos[0] = tot;
    ch[rt][1] = newnode(0 , -1);
    neg[0] = tot , fa[tot] = rt;
    upd(rt);
}

inline void rot(int u , int&aim) {
    int f = fa[u] , g = fa[f];
    int l = (ch[f][1] == u) , r = l ^ 1;
    if (f != aim) ch[g][ch[g][1] == f] = u;
    else aim = u;
    if (ch[u][r]) fa[ch[u][r]] = f;
    fa[f] = u , fa[u] = g;
    ch[f][l] = ch[u][r] , ch[u][r] = f;
    upd(f) , upd(u);
}

inline void splay(int u , int&aim) {
    for (;u != aim;rot(u , aim)) {
        int f = fa[u] , g = fa[f];
        if (f != aim) rot(((ch[f][0] == u) ^ (ch[g][0] == f)) ? u : f , aim);
    }
    upd(u);
}

inline int kth(int k) {
    int u = rt;
    while (sz[lc] + 1 != k) {
        if (sz[lc] + 1 < k)
            k -= sz[lc] + 1 , u = rc;
        else
            u = lc;
    }
    return u;
}

inline int kth_neg(int k) {
    int u = rt;
    for (;;) {
        if (val[u] < 0 || u == 2) {
            if (cnt[lc] + 1 == k) break;
            if (cnt[lc] + 1 > k)
                u = lc;
            else
                k -= cnt[lc] + 1 , u = rc;
        } else {
            if (cnt[lc] >= k)
                u = lc;
            else
                k -= cnt[lc] , u = rc;
        }
    }
    return u;
}

inline int find_pre(int u) {
    splay(u , rt);
    for (u = lc;rc;u = rc);
    return u;
}

inline int find_nxt(int u) {
    splay(u , rt);
    for (u = rc;lc;u = lc);
    return u;
}

inline void split(int u , int v) {
    splay(u , rt);
    splay(v , ch[u][1]);
}

inline void insert(int p) {
    int x = _num.get();
    split(kth(p + 1) , kth(p + 2));
    KEY = newnode(x , 1);
    fa[KEY] = ch[rt][1] , mt();
    splay(pos[x] , rt);
    int t = kth_neg(sz[ch[rt][0]] - cnt[ch[rt][0]]);
    split(find_pre(t) , t);
    KEY = newnode(x , -1);
    fa[KEY] = ch[rt][1] , mt();
    splay(neg[x] , rt);
}

inline void query(int x) {
    split(pos[x] , neg[x]);
    printf("%lld\n" , sum[KEY]);
}

inline void remove(int x) {
    split(find_pre(pos[x]) , find_nxt(pos[x]));
    delnode(KEY) , mt();
    split(find_pre(neg[x]) , find_nxt(neg[x]));
    delnode(KEY) , mt();
    _num.add(x);
    pos[x] = neg[x] = 0;
}

void solve() {
    char cmd[20];
    int p;
    rep (i , 1 , n) {
        scanf("%s%d" , cmd , &p);
        if (cmd[0] == 'i') {
            insert(p);
        } else if (cmd[0] == 'q') {
            query(p);
        } else if (cmd[0] == 'r') {
            remove(p);
        }
    }
}

int main() {
    #ifndef ONLINE_JUDGE
        freopen("data.txt" , "r" , stdin);
        freopen("data.out" , "w" , stdout);
    #endif
    int T = 1;
    while (scanf("%d" , &n) == 1) {
        printf("Case #%d:\n" , T ++);
        input();
        solve();
    }
    return 0;
}

你可能感兴趣的:(2012 Asia Tianjin Regional Contest - Queue Sequence)