您的位置:首页 > 产品设计 > UI/UE

【HDOJ】3436 Queue-jumpers

2015-10-25 13:28 501 查看
离散化+伸展树。

/* 3436 */
#include <iostream>
#include <string>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>
#include <deque>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <ctime>
#include <cstring>
#include <climits>
#include <cctype>
#include <cassert>
#include <functional>
#include <iterator>
#include <iomanip>
using namespace std;
//#pragma comment(linker,"/STACK:102400000,1024000")

#define sti                set<int>
#define stpii            set<pair<int, int> >
#define mpii            map<int,int>
#define vi                vector<int>
#define pii                pair<int,int>
#define vpii            vector<pair<int,int> >
#define rep(i, a, n)     for (int i=a;i<n;++i)
#define per(i, a, n)     for (int i=n-1;i>=a;--i)
#define clr                clear
#define pb                 push_back
#define mp                 make_pair
#define fir                first
#define sec                second
#define all(x)             (x).begin(),(x).end()
#define SZ(x)             ((int)(x).size())
#define lson            l, mid, rt<<1
#define rson            mid+1, r, rt<<1|1
#define grandlson         ch[ch[root][1]][0]

typedef struct {
char c;
int x;
} Cmd;

const int maxq = 1e5+5;
const int maxn = 3e5+5;
int pre[maxn], ch[maxn][2], s[maxn], key[maxn], pos[maxn];
int arr[maxn], cnt[maxn];
int b[maxn], e[maxn];
int tot, root, n, m;
Cmd cmd[maxq];

int search(int x) {
int l = 0, r = m - 1, mid;
int ret = -1;

while (l <= r) {
mid = (l + r) >> 1;
if (b[mid]<=x && x<=e[mid])
return mid;
if (e[mid] < x) {
l = mid + 1;
} else {
r = mid - 1;
}
}

return ret;
}

void newNode(int& r, int k, int fa) {
r = tot++;
pre[r] = fa;
ch[r][0] = ch[r][1] = 0;
key[r] = k;
pos[k] = r;
s[r] = cnt[r] = e[k] - b[k] + 1;
}

void PushUp(int r) {
s[r] = s[ch[r][0]] + s[ch[r][1]] + cnt[r];
}

void Build(int& rt, int l, int r, int fa) {
if (l >    r)    return;

int mid = (l + r) >>1;

newNode(rt, mid, fa);
Build(ch[rt][0], l, mid-1, rt);
Build(ch[rt][1], mid+1, r, rt);
PushUp(rt);
}

void Rotate(int x, int d) {
int y = pre[x];
ch[y][d^1] = ch[x][d];
pre[ch[x][d]] = y;
if (pre[y])
ch[pre[y]][ch[pre[y]][1]==y] = x;
pre[x] = pre[y];
ch[x][d] = y;
pre[y] = x;
PushUp(y);
}

void Splay(int r, int goal) {
while (pre[r] != goal) {
if (pre[pre[r]] == goal) {
Rotate(r, ch[pre[r]][0]==r);
} else {
int y = pre[r];
int d = (ch[pre[y]][0] == y);
if (ch[y][d] == r) {
Rotate(r, d^1);
Rotate(r, d);
}  else {
Rotate(y, d);
Rotate(r, d);
}
}
}
PushUp(r);
if (goal == 0)
root = r;
}

void Insert(int& r, int k, int fa) {
if (r == 0) {
newNode(r, k, fa);
return ;
}
Insert(ch[r][0], k, r);
PushUp(r);
}

int getMin(int r) {
while (ch[r][0]) {
r = ch[r][0];
}
return r;
}

int kth(int r, int k) {
int sz = s[ch[r][0]];

if (k <= sz)
return kth(ch[r][0], k);
else if (k <= sz+cnt[r])
return b[key[r]] + k - sz - 1;
else
return kth(ch[r][1], k-sz-cnt[r]);
}

int Rank(int x) {
return kth(root, x);
}

int Query(int x) {
int k = search(x);
int p = pos[k];

Splay(p, 0);
return s[ch[root][0]] + 1;
}

void Delete() {
int k = getMin(ch[root][1]);

Splay(k, root);
ch[ch[root][1]][0] = ch[root][0];
root = ch[root][1];
pre[ch[root][0]] = root;
pre[root] = 0;
PushUp(root);
}

void top(int x) {
int k = search(x);
int p = pos[k];

Splay(p, 0);
if (ch[root][0]==0 || ch[root][1]==0) {
root = ch[root][0] + ch[root][1];
pre[root] = 0;
} else {
Delete();
}
Insert(root, k, 0);
Splay(pos[k], 0);
}

void inorder(int rt) {
if (rt == 0)    return ;

inorder(ch[rt][0]);
printf("rt = %2d: lson = %2d, rson = %2d, fa = %2d, size = %2d, key = %2d, num = %2d \n",
rt, ch[rt][0], ch[rt][1], pre[rt], s[rt], key[rt], cnt[rt]);
inorder(ch[rt][1]);
}

void init() {
root = tot = 0;
ch[root][0] = ch[root][1] = s[root] = pre[root] = cnt[root] = key[root] = 0;
tot = 1;
Build(root, 0, m-1, 0);
#ifndef ONLINE_JUDGE
// inorder(root);
#endif
}

int main() {
ios::sync_with_stdio(false);
#ifndef ONLINE_JUDGE
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
#endif

int t, q;
int l, x;
int ans;
char event[10];

scanf("%d", &t);
rep(tt, 1, t+1) {
printf("Case %d:\n", tt);
scanf("%d %d", &n, &q);
l = 0;
arr[l++] = 0;
rep(i, 0, q) {
scanf("%s %d", event, &cmd[i].x);
if (event[0] != 'R')
arr[l++] = cmd[i].x;
cmd[i].c = event[0];
}
arr[l++] = n;
sort(arr, arr+l);

m = 0;
rep(i, 1, l) {
if (arr[i] != arr[i-1]) {
if (arr[i]-arr[i-1] > 1) {
b[m] = arr[i-1] + 1;
e[m] = arr[i] - 1;
++m;
}
b[m] = e[m] = arr[i];
++m;
}
}

init();
rep(i, 0, q) {
if (cmd[i].c == 'T') {
top(cmd[i].x);
} else if (cmd[i].c == 'Q') {
ans = Query(cmd[i].x);
printf("%d\n", ans);
} else {
ans = Rank(cmd[i].x);
printf("%d\n", ans);
}
#ifndef ONLINE_JUDGE
printf("iteration [%d]:\n", i);
inorder(root);
#endif
}
}

#ifndef ONLINE_JUDGE
printf("time = %d.\n", (int)clock());
#endif

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