OJ-Problems-Source/.ACM-Templates/TXTs/数据结构.txt

2210 lines
58 KiB
Plaintext
Raw Normal View History

2016-11-22 09:38:35 +08:00
//һά<D2BB><CEAC>״<EFBFBD><D7B4><EFBFBD><EFBFBD>
//<2F><><EFBFBD><EFBFBD><EFBFBD>޸<EFBFBD> + <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѯ + <20><><EFBFBD><EFBFBD><EFBFBD>޸<EFBFBD> + <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѯ + <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ
int n;
template<typename T> struct BIT {
T A[N]; //T B[N]; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><><CEAC><EFBFBD><EFBFBD>ֵ
int lowbit(int x) { return x & -x; }
void init() { memset(A, 0, sizeof(A)); /*memset(B, 0, sizeof(B));*/ }
void update(int i, T v) { while (i <= n) { A[i] += v; i += lowbit(i); } }
T query(int i) { T ret = 0; while (i) { ret += A[i]; i -= lowbit(i); } return ret; }
T query(int i, int j) { return query(j) - query(i - 1); }
//<2F><><EFBFBD><EFBFBD><EFBFBD>޸<EFBFBD>
T query(int x) {
if (!x) { return 0; }
T ret1 = 0, ret2 = 0;
for (int i = x; i <= n; i += lowbit(i)) { ret1 += A[i]; }
for (int i = x - 1; i > 0; i -= lowbit(i)) { ret2 += B[i]; }
return ret1 * x + ret2;
}
void update(int x, T v) {
for (int i = x; i > 0; i -= lowbit(i)) { A[i] += v; }
for (int i = x; i <= n; i += lowbit(i)) { B[i] += x * v; }
}
void update(int i, int j, T v) { update(j, v); if (i > 1) { update(i - 1, -v); } }
//ά<><CEAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ O(log^2(n))
void modify(int x, T v) {
B[x] = v;
for (int i = x; i <= n; i += lowbit(i)) {
A[i] = max(A[i], v);
for (int j = 1; j < lowbit(i); j <<= 1) {
A[i] = max(A[i], A[i - j]);
}
}
}
T query(int l, int r) {
T ret = B[r];
while (true) {
ret = max(ret, B[r]);
if (l == r) { break; }
for (r -= 1; r - l >= lowbit(r); r -= lowbit(r)) { ret = max(ret, A[r]); }
}
return ret;
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>K<EFBFBD><4B><EFBFBD><EFBFBD><EFBFBD>±<EFBFBD>/ֵ O(log^2(n))
int getK(int l, int r, int k) {
while (l <= r) {
int mid = l + ((r - l) >> 1);
if (query(mid) >= k) { r = mid - 1; }
else { l = mid + 1; }
}
return l; //A[l]
}
};
BIT<int> bit;
//<2F><>ά<EFBFBD><CEAC>״<EFBFBD><D7B4><EFBFBD><EFBFBD>
//<2F><><EFBFBD><EFBFBD><EFBFBD>޸<EFBFBD> + <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѯ + <20><><EFBFBD><EFBFBD><EFBFBD>޸<EFBFBD> + <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѯ
int n, m;
template<typename T> struct BIT {
T A[N][N]; //T B[N][N], C[N][N], D[N][N]; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
int lowbit(int x) { return x & -x; }
void init() { memset(A, 0, sizeof(A)); /*memset(B, 0, sizeof(B)); memset(C, 0, sizeof(C)); memset(D, 0, sizeof(D));*/ }
T get(int x, int y) {
T ret = 0;
for (int i = x; i > 0; i -= lowbit(i)) { for (int j = y; j > 0; j -= lowbit(j)) { ret += A[i][j]; } }
return ret;
}
T query(int x, int y) { return get(x, y) - get(x, y - 1) - get(x - 1, y) + get(x - 1, y - 1); }
void update(int x, int y, T v) {
for (int i = x; i <= n; i += lowbit(i)) { for (int j = y; j <= m; j += lowbit(j)) { A[i][j] += v; } }
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>[x1][y1]-[x2][y2]
T query(int x1, int y1, int x2, int y2) {
return get(x2, y2) - get(x1 - 1, y2) - get(x2, y1 - 1) + get(x1 - 1, y1 - 1);
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void update(int x, int y, T v, T a[][N]) {
for (int i = x; i <= n; i += lowbit(i)) { for (int j = y; j <= m; j += lowbit(j)) { a[i][j] += v; } }
}
void update(int x1, int y1, int x2, int y2, T v) {
update(x1, y1, v, A); update(x2 + 1, y1, -v, A);
update(x1, y2 + 1, -v, A); update(x2 + 1, y2 + 1, v, A);
update(x1, y1, v * x1, B); update(x2 + 1, y1, -v * (x2 + 1), B);
update(x1, y2 + 1, -v * x1, B); update(x2 + 1, y2 + 1, v * (x2 + 1), B);
update(x1, y1, v * y1, C); update(x2 + 1, y1, -v * y1, C);
update(x1, y2 + 1, -v * (y2 + 1), C); update(x2 + 1, y2 + 1, v * (y2 + 1), C);
update(x1, y1, v * x1 * y1, D); update(x2 + 1, y1, -v * (x2 + 1) * y1, D);
update(x1, y2 + 1, -v * x1 * (y2 + 1), D); update(x2 + 1, y2 + 1, v * (x2 + 1) * (y2 + 1), D);
}
};
BIT<int> bit;
//<2F>߶<EFBFBD><DFB6><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>޸<EFBFBD> + <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѯ
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
template<typename T> struct SegmentTree {
T data[N << 2];
T calc(const T &x, const T &y)const { return x + y; }
void push_up(int rt) { data[rt] = calc(data[rt << 1], data[rt << 1 | 1]); }
void build(int l, int r, int rt) {
if (l == r) { scanf("%d", &data[rt]); return; }
int m = (l + r) >> 1;
build(lson);
build(rson);
push_up(rt);
}
void update(int p, T val, int l, int r, int rt) {
if (l == r) { data[rt] += val; return; }
int m = (l + r) >> 1;
if (p <= m) { update(p, val, lson); }
else { update(p, val, rson); }
push_up(rt);
}
T query(int L, int R, int l, int r, int rt) {
if (L <= l && r <= R) { return data[rt]; }
int m = (l + r) >> 1; T ret = 0;
if (L <= m) { ret = calc(ret, query(L, R, lson)); }
if (m < R) { ret = calc(ret, query(L, R, rson)); }
return ret;
}
};
SegmentTree<int> st;
//<2F>߶<EFBFBD><DFB6><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѯ/<2F>޸<EFBFBD> + <20>ӳٱ<D3B3><D9B1><EFBFBD>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
template<typename T> struct SegmentTree {
T data[N << 2], lazy[N << 2];
T calc(const T &x, const T &y)const { return x + y; }
void push_up(int rt) { data[rt] = calc(data[rt << 1], data[rt << 1 | 1]); }
void push_down(int rt, int len) {
if (lazy[rt]) {
data[rt << 1] += lazy[rt] * (len - (len >> 1)); lazy[rt << 1] += lazy[rt];
data[rt << 1 | 1] += lazy[rt] * (len >> 1); lazy[rt << 1 | 1] += lazy[rt];
lazy[rt] = 0;
}
}
void build(int l, int r, int rt) {
lazy[rt] = 0;
if (l == r) { scanf("%d", &data[rt]); return; }
int m = (l + r) >> 1;
build(lson);
build(rson);
push_up(rt);
}
void update(int L, int R, T val, int l, int r, int rt) {
if (L <= l && r <= R) {
data[rt] += val * (r - l + 1);
lazy[rt] += val;
return;
}
push_down(rt, r - l + 1);
int m = (l + r) >> 1;
if (L <= m) { update(L, R, val, lson); }
if (m < R) { update(L, R, val, rson); }
push_up(rt);
}
T query(int L, int R, int l, int r, int rt) {
if (L <= l && r <= R) { return data[rt]; }
push_down(rt, r - l + 1);
int m = (l + r) >> 1; T ret = 0;
if (L <= m) { ret = calc(ret, query(L, R, lson)); }
if (m < R) { ret = calc(ret, query(L, R, rson)); }
return ret;
}
};
SegmentTree<int> st;
//<2F>ǵݹ<C7B5><DDB9><EFBFBD><EFBFBD>߶<EFBFBD><DFB6><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>޸<EFBFBD> + <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѯ
const int N = ((131072 << 1) + 10); //<2F>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD>-><3E><>С<EFBFBD><D0A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E4B3A4>+2<><32><EFBFBD><EFBFBD>С2<D0A1><32><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>*2+10
#define l(x) ((x)<<1) //x<><78><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
#define r(x) (((x)<<1)|1) //x<><78><EFBFBD>Ҷ<EFBFBD><D2B6><EFBFBD>
template<typename T> struct zkwSegmentTree {
int m; //<2F>ײ<EFBFBD><D7B2>ڵ<EFBFBD><DAB5><EFBFBD>
T sum[N]; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void build(int n) {
for (m = 1; m < n + 2; m <<= 1);
for (int i = 1; i <= n; i++) { scanf("%d", &sum[m + i]); }
for (int i = m - 1; i; i--) { sum[i] = sum[l(i)] + sum[r(i)]; }
}
void update(int p, T val) {
for (sum[p += m] += val, p >>= 1; p; p >>= 1) {
sum[p] = sum[l(p)] + sum[r(p)];
}
}
T query(int l, int r) {
T ret = 0;
for (l += m - 1, r += m + 1; l ^ r ^ 1; l >>= 1, r >>= 1) {
if (~l & 1) { ret += sum[l ^ 1]; }
if (r & 1) { ret += sum[r ^ 1]; }
}
return ret;
}
};
zkwSegmentTree<int> st;
//<2F>ǵݹ<C7B5><DDB9><EFBFBD><EFBFBD>߶<EFBFBD><DFB6><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѯ/<2F>޸<EFBFBD> + <20>ӳٱ<D3B3><D9B1><EFBFBD>
const int N = ((131072 << 1) + 10); //<2F>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD>-><3E><>С<EFBFBD><D0A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E4B3A4>+2<><32><EFBFBD><EFBFBD>С2<D0A1><32><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>*2+10
#define l(x) ((x)<<1) //x<><78><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
#define r(x) (((x)<<1)|1) //x<><78><EFBFBD>Ҷ<EFBFBD><D2B6><EFBFBD>
template<typename T> struct zkwSegmentTree {
int m, h; //<2F>ײ<EFBFBD><D7B2>ڵ<EFBFBD><DAB5><EFBFBD> <20>߶<EFBFBD>
T sum[N], add[N]; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ӳٱ<D3B3><D9B1><EFBFBD>
void pushdown(int rt) {
for (int i = h, p; i; i--) { //<2F>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD>
if (add[p = rt >> i]) {
add[p] >>= 1; //add[p]Ϊ<>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20>ӽڵ<D3BD><DAB5><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>
sum[l(p)] += add[p]; add[l(p)] += add[p];
sum[r(p)] += add[p]; add[r(p)] += add[p];
add[p] = 0;
}
}
}
void build(int n) {
for (m = 1, h = 0; m < n + 2; m <<= 1, h++);
for (int i = 1; i <= n; i++) { scanf("%d", &sum[m + i]); }
for (int i = m - 1; i; i--) { sum[i] = sum[l(i)] + sum[r(i)]; }
}
void update(int l, int r, T val) {
l += m - 1, r += m + 1; int ll = l >> 1, rr = r >> 1;
for (pushdown(l), pushdown(r); l ^ r ^ 1; l >>= 1, r >>= 1, val <<= 1) {
if (~l & 1) { sum[l ^ 1] += val; add[l ^ 1] += val; }
if (r & 1) { sum[r ^ 1] += val; add[r ^ 1] += val; }
}
for (; ll; ll >>= 1) { sum[ll] = sum[l(ll)] + sum[r(ll)]; }
for (; rr; rr >>= 1) { sum[rr] = sum[l(rr)] + sum[r(rr)]; }
}
T query(int l, int r) {
T ret = 0; l += m - 1, r += m + 1;
for (pushdown(l), pushdown(r); l ^ r ^ 1; l >>= 1, r >>= 1) {
if (~l & 1) { ret += sum[l ^ 1]; }
if (r & 1) { ret += sum[r ^ 1]; }
}
return ret;
}
};
zkwSegmentTree<int> st;
//<2F>ɳ־û<D6BE><C3BB>߶<EFBFBD><DFB6><EFBFBD>
const int N = 100005;
const int M = 2500005;
const int INF = 0x3f3f3f3f;
int n, m, nn; //<2F><>ɢ<EFBFBD><C9A2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С
#define lson l,m,ls[rt]
#define rson m+1,r,rs[rt]
template<typename T> struct SegmentTree {
int ls[M], rs[M], root[N], tot; T data[M];
int new_node() { return ++tot; }
void build(int l, int r, int &rt) {
rt = new_node(); data[rt] = 0;
if (l == r) { return; }
int m = (l + r) >> 1;
build(lson);
build(rson);
}
void update(int p, T val, int lst, int l, int r, int &rt) {
rt = new_node(); ls[rt] = ls[lst]; rs[rt] = rs[lst]; data[rt] = data[lst] + val;
if (l == r) { return; }
int m = (l + r) >> 1;
if (p <= m) { update(p, val, ls[lst], lson); }
else { update(p, val, rs[lst], rson); }
}
//<2F><><EFBFBD>޸<EFBFBD><DEB8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>kС
int tree[N], use[N];
int lowbit(int x) { return x & -x; }
void modify(int x, int p, T val) { //xΪԭ<CEAA><D4AD><EFBFBD><EFBFBD><EFBFBD>е<EFBFBD><D0B5>±<EFBFBD>, pΪֵ
for (int i = x; i <= n; i += lowbit(i)) { update(p, val, tree[i], 1, nn, tree[i]); }
}
T query(int x) {
T ret = 0;
for (int i = x; i; i -= lowbit(i)) { ret += data[ls[use[i]]]; }
return ret;
}
int query(int L, int R, int k, int l, int r) {
for (int i = L; i; i -= lowbit(i)) { use[i] = tree[i]; }
for (int i = R; i; i -= lowbit(i)) { use[i] = tree[i]; }
int lr = root[L], rr = root[R];
while (l < r) {
int m = (l + r) >> 1; T tmp = query(R) - query(L) + data[ls[rr]] - data[ls[lr]];
if (k <= tmp) {
r = m;
for (int i = L; i; i -= lowbit(i)) { use[i] = ls[use[i]]; }
for (int i = R; i; i -= lowbit(i)) { use[i] = ls[use[i]]; }
lr = ls[lr]; rr = ls[rr];
} else {
l = m + 1; k -= tmp;
for (int i = L; i; i -= lowbit(i)) { use[i] = rs[use[i]]; }
for (int i = R; i; i -= lowbit(i)) { use[i] = rs[use[i]]; }
lr = rs[lr]; rr = rs[rr];
}
}
return l;
}
};
SegmentTree<int> st;
//ZOJ 2112
int a[N], hs[N], l[N], r[N], k[N];
char op[N];
int main() {
int C = 0, T;
scanf("%d", &T);
while (++C <= T) {
nn = 0;
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++) {
scanf("%d", &a[i]); hs[++nn] = a[i];
}
for (int i = 0; i < m; i++) {
scanf(" %c%d%d", &op[i], &l[i], &r[i]);
switch (op[i]) {
case 'Q': scanf("%d", &k[i]); break;
case 'C': hs[++nn] = r[i]; break;
}
}
sort(hs + 1, hs + nn + 1);
nn = unique(hs + 1, hs + nn + 1) - hs - 1;
for (int i = 1; i <= n; ++i) {
a[i] = lower_bound(hs + 1, hs + nn + 1, a[i]) - hs;
}
st.tot = 0;
st.build(1, nn, st.root[0]);
for (int i = 1; i <= n; i++) {
st.update(a[i], 1, st.root[i - 1], 1, nn, st.root[i]);
}
for (int i = 1; i <= n; i++) { st.tree[i] = st.root[0]; }
for (int i = 0; i < m; i++) {
switch (op[i]) {
case 'Q':
printf("%d\n", hs[st.query(l[i] - 1, r[i], k[i], 1, nn)]);
break;
case 'C':
st.modify(l[i], a[l[i]], -1);
a[l[i]] = lower_bound(hs + 1, hs + nn + 1, r[i]) - hs;
st.modify(l[i], a[l[i]], 1);
break;
}
}
}
}
//ʵʱ<CAB5><CAB1><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD>Ȩֵ<C8A8>߶<EFBFBD><DFB6><EFBFBD> (<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɢ<EFBFBD><C9A2>) O(logV)
const int N = 60005;
const int M = 2500005;
const int INF = 0x3f3f3f3f;
int n, a[N];
#define lson l,m,ls[rt]
#define rson m+1,r,rs[rt]
struct SegmentTree {
int ls[M], rs[M], cnt[M], root[N], tot;
void init() {
tot = 0; memset(cnt, 0, sizeof(cnt)); memset(root, 0, sizeof(root));
memset(ls, 0, sizeof(ls)); memset(rs, 0, sizeof(rs));
}
int new_node() { return ++tot; }
void update(int p, int val, int l, int r, int &rt) {
if (!rt) { rt = new_node(); }
if (l == r) { cnt[rt] += val; return; }
int m = (l + r) >> 1;
if (p <= m) { update(p, val, lson); }
else { update(p, val, rson); }
cnt[rt] = cnt[ls[rt]] + cnt[rs[rt]];
}
int use[N];
int lowbit(int x) { return x & -x; }
//<2F><><EFBFBD><EFBFBD><EFBFBD>޸<EFBFBD>
void modify(int x, int p, int val) {
for (int i = x; i <= n; i += lowbit(i)) { update(p, val, 0, INF, root[i]); }
}
int query(int x) {
int ret = 0;
for (int i = x; i; i -= lowbit(i)) { ret += cnt[ls[use[i]]]; }
return ret;
}
//<2F><>ѯ<EFBFBD><D1AF><EFBFBD><EFBFBD><EFBFBD><EFBFBD>kС
int query(int L, int R, int k, int l, int r) {
for (int i = L; i; i -= lowbit(i)) { use[i] = root[i]; }
for (int i = R; i; i -= lowbit(i)) { use[i] = root[i]; }
while (l < r) {
int m = (l + r) >> 1, tmp = query(R) - query(L);
if (k <= tmp) {
r = m;
for (int i = L; i; i -= lowbit(i)) { use[i] = ls[use[i]]; }
for (int i = R; i; i -= lowbit(i)) { use[i] = ls[use[i]]; }
} else {
l = m + 1; k -= tmp;
for (int i = L; i; i -= lowbit(i)) { use[i] = rs[use[i]]; }
for (int i = R; i; i -= lowbit(i)) { use[i] = rs[use[i]]; }
}
}
return l;
}
} st;
//BZOJ1901 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>kС
int main() {
int m, l, r, k; char op[5];
while (~scanf("%d%d", &n, &m)) {
st.init();
for (int i = 1; i <= n; ++i) {
scanf("%d", &a[i]);
st.modify(i, a[i], 1);
}
while (m--) {
scanf("%s%d%d", op, &l, &r);
switch (op[0]) {
case 'Q':
scanf("%d", &k);
printf("%d\n", st.query(l - 1, r, k, 0, INF));
break;
case 'C':
st.modify(l, a[l], -1);
a[l] = r;
st.modify(l, a[l], 1);
break;
}
}
}
}
//ƽ<><C6BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ò<EFBFBD><C3B2><EFBFBD>
//ע<><D7A2><EFBFBD><EFBFBD>Щ<EFBFBD><D0A9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڲ<EFBFBD><DAB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ظ<EFBFBD>ֵ<EFBFBD><D6B5>ƽ<EFBFBD><C6BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(set<65><74><EFBFBD><EFBFBD>multiset)
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ظ<EFBFBD>ֵ(ӵ<><D3B5>cnt<6E><74>)<29><>ʵ<EFBFBD><CAB5>, ֻҪ<D6BB><D2AA>һЩ+1<>ĵط<C4B5><D8B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>޸<EFBFBD>(<28>ij<EFBFBD>cnt[x])<29><><EFBFBD><EFBFBD>
bool find(int v) {
for (int x = root; x; x = ch[x][key[x] < v]) {
if (key[x] == v) { return true; }
}
return false;
}
int getKth(int k) {
int x = root;
while (size[ch[x][0]] + 1 != k) {
if (k < size[ch[x][0]] + 1) { x = ch[x][0]; }
else { k -= size[ch[x][0]] + 1; x = ch[x][1]; }
}
return key[x];
}
int getRank(int v) {
int ret = 0, x = root;
while (x) {
if (v < key[x]) { x = ch[x][0]; }
else { ret += size[ch[x][0]] + 1; x = ch[x][1]; }
}
return ret;
}
int getPre(int v) {
int x = root, y = 0;
while (x) {
if (v < key[x]) { x = ch[x][0]; }
else { y = x; x = ch[x][1]; }
}
return y;
}
int getNext(int v) {
int x = root, y = 0;
while (x) {
if (v > key[x]) { x = ch[x][1]; }
else { y = x; x = ch[x][0]; }
}
return y;
}
int getMin() {
if (size[root] == 0) { return -1; }
int x = root;
while (ch[x][0]) { x = ch[x][0]; }
return x;
}
int getMax() {
if (size[root] == 0) { return -1; }
int x = root;
while (ch[x][1]) { x = ch[x][1]; }
return x;
}
//Debug<75><67><EFBFBD><EFBFBD>
void treaval(int x) {
if (x != 0) {
treaval(ch[x][0]);
printf("Node%2d:lson %2d rson %2d size = %2d ,val = %2d\n", x, ch[x][0], ch[x][1], size[x], key[x]);
treaval(ch[x][1]);
}
}
void debug() {
printf("root:%d\n", root);
treaval(root);
putchar('\n');
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ת<EFBFBD><D7AA>Treap <20><><EFBFBD><EFBFBD><EFBFBD>ظ<EFBFBD>ֵ
//ά<><CEAC><EFBFBD><EFBFBD><EFBFBD>е<EFBFBD><D0B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԺͶѵ<CDB6><D1B5><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,
//<2F><><EFBFBD><EFBFBD><EFBFBD>ĸ߶<C4B8>ά<EFBFBD><CEAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƽ<EFBFBD><C6BD><EFBFBD>ij̶<C4B3>,<2C>Ӷ<EFBFBD>ʵ<EFBFBD><CAB5><EFBFBD>˸<EFBFBD><CBB8>ֲ<EFBFBD><D6B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>O(logn)<29>ĸ<EFBFBD><C4B8>Ӷ<EFBFBD>.
//<2F><><EFBFBD><EFBFBD><EFBFBD>Լ۱ȸ<DBB1><C8B8><EFBFBD>ֻ<EFBFBD><D6BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ת(<28><><EFBFBD>ҿ<EFBFBD><D2BF>Ժϲ<D4BA><CFB2><EFBFBD>д), <20>Ⱥ<EFBFBD><C8BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>AVL<56><4C>С
struct Treap {
int tot, root;
int ch[N][2], key[N], pt[N], cnt[N], size[N];
void init() { tot = root = 0; pt[0] = INF; }
void push_up(int x) { size[x] = size[ch[x][0]] + size[ch[x][1]] + cnt[x]; }
void new_node(int &x, int v) {
x = ++tot;
ch[x][0] = ch[x][1] = 0;
size[x] = cnt[x] = 1;
pt[x] = rand();
key[x] = v;
}
void rotate(int &x, int f) {
int y = ch[x][f];
ch[x][f] = ch[y][f ^ 1];
ch[y][f ^ 1] = x;
push_up(x);
push_up(y);
x = y;
}
void insert(int &x, int v) {
if (!x) { new_node(x, v); return; }
if (key[x] == v) {
++cnt[x];
} else {
int f = key[x] < v;
insert(ch[x][f], v);
if (pt[ch[x][f]] < pt[x]) {
rotate(x, f);
}
}
push_up(x);
}
void erase(int &x, int v) {
if (!x) { return; }
if (key[x] == v) {
if (cnt[x] > 1) {
--cnt[x];
} else {
if (!ch[x][0] && !ch[x][1]) {
x = 0;
} else {
rotate(x, pt[ch[x][0]] > pt[ch[x][1]]);
erase(x, v);
}
}
} else {
erase(ch[x][key[x] < v], v);
}
push_up(x);
}
void insert(int v) { insert(root, v); }
void erase(int v) { erase(root, v); }
} treap;
//Size Balanced Tree <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ظ<EFBFBD>ֵ
//<2F><><EFBFBD>ص<EFBFBD>ƽ̯ʱ<CCAF><CAB1>O(1)<29><>Maintain<69><6E><EFBFBD><EFBFBD>, <20><><EFBFBD>н<EFBFBD><D0BD><EFBFBD><EFBFBD>ں<EFBFBD><DABA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>Ч<EFBFBD><D0A7>
struct SBT {
int root, tot;
int ch[N][2], key[N], size[N];
void init() { tot = root = 0; size[0] = 0; }
void rotate(int &x, int f) {
int y = ch[x][f];
ch[x][f] = ch[y][f ^ 1];
ch[y][f ^ 1] = x;
size[y] = size[x];
size[x] = size[ch[x][0]] + size[ch[x][1]] + 1;
x = y;
}
void maintain(int &x, int f) {
if (size[ch[ch[x][f]][f]] > size[ch[x][f ^ 1]]) {
rotate(x, f);
} else if (size[ch[ch[x][f]][f ^ 1]] > size[ch[x][f ^ 1]]) {
rotate(ch[x][f], f ^ 1); rotate(x, f);
} else {
return;
}
maintain(ch[x][0], 0);
maintain(ch[x][1], 1);
maintain(x, 0);
maintain(x, 1);
}
void insert(int &x, int v) {
if (!x) {
x = ++tot;
ch[x][0] = ch[x][1] = 0;
size[x] = 1;
key[x] = v;
} else {
++size[x];
insert(ch[x][key[x] < v], v);
maintain(x, key[x] < v);
}
}
int erase(int &x, int v) {
if (!x) { return 0; }
--size[x];
if (key[x] == v || (key[x] > v && !ch[x][0]) || (key[x] < v && !ch[x][1])) {
int ret = key[x];
if (ch[x][0] && ch[x][1]) {
key[x] = erase(ch[x][0], v + 1);
} else {
x = ch[x][0] + ch[x][1];
}
return ret;
}
return erase(ch[x][key[x] < v], v);
}
void insert(int v) { insert(root, v); }
void erase(int v) { erase(root, v); }
} sbt;
//Splay
//<2F><><EFBFBD><EFBFBD>ʵ<EFBFBD>ֺܶ<D6BA><DCB6><EFBFBD><EFBFBD><EFBFBD>ƽ<EFBFBD><C6BD><EFBFBD><EFBFBD><EFBFBD>޷<EFBFBD>ʵ<EFBFBD>ֵIJ<D6B5><C4B2><EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD>䷭ת), <20>ȿ<EFBFBD><C8BF><EFBFBD>ά<EFBFBD><CEAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ,
//Ҳ<><D2B2><EFBFBD><EFBFBD>ά<EFBFBD><CEAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Treap<61><70><EFBFBD><EFBFBD>, Ҳ<><D2B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߶<EFBFBD><DFB6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
//<2F><><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD>, Splay<61><79><EFBFBD><EFBFBD>ʵ<EFBFBD><CAB5>split(<28><>ij<EFBFBD><C4B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><D4AD><EFBFBD>з<EFBFBD><D0B7><EFBFBD>)<29><>merge<67><65><EFBFBD><EFBFBD>(<28><>ij<EFBFBD><C4B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>),
//<2F><>Ҳʹ<D2B2><CAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɾ<EFBFBD><C9BE><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD>. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>в<EFBFBD><D0B2><EFBFBD><EFBFBD>dz<EFBFBD><C7B3><EFBFBD><EFBFBD>Դ<EFBFBD>, Լ<><D4BC>Treap<61><70>1.5<EFBFBD><EFBFBD>3<EFBFBD><EFBFBD>, <20>߶<EFBFBD><DFB6><EFBFBD><EFBFBD><EFBFBD>2<EFBFBD><32>5<EFBFBD><35>.
//Splay<61>е<EFBFBD><D0B5><EFBFBD><EFBFBD><EFBFBD>˫<EFBFBD><CBAB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><CAB5>, <20><><EFBFBD><EFBFBD>ֻ<EFBFBD><D6BB>˫<EFBFBD><CBAB><EFBFBD><EFBFBD>֤<EFBFBD>˾<EFBFBD>̯O(logn)<29>ĵ<EFBFBD><C4B5>β<EFBFBD><CEB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӷ<EFBFBD>,
//<2F><><EFBFBD><EFBFBD>Ϊ<EFBFBD>ܶ<EFBFBD><DCB6><EFBFBD><EFBFBD><EFBFBD>Ϊzigzag̫<67><CCAB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>OIѡ<49><D1A1><EFBFBD>д<EFBFBD><D0B4><EFBFBD><EFBFBD><EFBFBD>), ѡ<><D1A1><EFBFBD>˵<EFBFBD><CBB5><EFBFBD>.
//<2F><>ʵ<EFBFBD><CAB5>ȫ<EFBFBD><C8AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>΢<EFBFBD><CEA2>ʧһ<CAA7><EFBFBD><E3B3A3>, <20>ϲ<EFBFBD><CFB2><EFBFBD>һ<EFBFBD><D2BB>rotate<74><65><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˫<EFBFBD><CBAB>.
//<2F><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD>õ<EFBFBD>ʵ<EFBFBD><CAB5>ͨ<EFBFBD><CDA8>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>һβ<D2BB><CEB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڱ<EFBFBD><DAB1>ڵ<EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Լ<EFBFBD><D4BC>ٺܶ<D9BA><DCB6>߽<EFBFBD><DFBD><EFBFBD><EFBFBD><EFBFBD>.
//<2F>б<EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD>е<EFBFBD><D0B5><EFBFBD>չ<EFBFBD><D5B9>˵<EFBFBD><CBB5><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫά<D2AA><CEAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ, <20><><EFBFBD>ǿ<EFBFBD><C7BF><EFBFBD><EFBFBD><EFBFBD>Splayά<79><CEAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(dfs<66><73>),
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>split<69><74><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E4A3BB><EFBFBD><EFBFBD>Splayά<79><CEAC>dfs<66><73><EFBFBD>Ľṹ, <20><><EFBFBD><EFBFBD>Euler-Tour Tree.
//ͬ<><CDAC><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫά<D2AA><CEAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʷ<EFBFBD>Ȼ<EFBFBD><C8BB><EFBFBD><EFBFBD>Splayά<79><CEAC>ÿ<EFBFBD><C3BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>07<30><37><EFBFBD><EFBFBD><EFBFBD>Ҽ<EFBFBD>ѵ<EFBFBD><D1B5><EFBFBD><EFBFBD>ҵ<EFBFBD>ļ<EFBFBD><C4BC><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܷ<EFBFBD><DCB7><EFBFBD><EFBFBD>õ<EFBFBD><C3B5>ĸ<EFBFBD><C4B8>Ӷ<EFBFBD><D3B6><EFBFBD>Ȼ<EFBFBD>ǵ<EFBFBD><C7B5>β<EFBFBD><CEB2><EFBFBD><EFBFBD><EFBFBD>̯O(logn)<29><><EFBFBD>Ӷ<EFBFBD>;
//<2F><><EFBFBD><EFBFBD><EFBFBD>Ƶ<EFBFBD>˼<EFBFBD><CBBC><EFBFBD><EFBFBD>Щת<D0A9><D7AA>, <20>ͱ<EFBFBD><CDB1><EFBFBD><EFBFBD>˺<EFBFBD><CBBA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E1B5BD>Link-Cut Tree(<28><><EFBFBD>¼<EFBFBD><C2BC><EFBFBD>LCT).
//ver.1
#define keyTree (ch[ch[root][1]][0])
const int N = 200005;
const int INF = 0x3f3f3f3f;
int num[N];
struct Splay {
int root, tot1, tot2;
int ch[N][2], pre[N], size[N];
int gc[N], que[N];
int key[N], vmin[N], add[N], rev[N];
void rotate(int x, int f) {
int y = pre[x];
ch[y][f ^ 1] = ch[x][f];
pre[ch[x][f]] = y;
pre[x] = pre[y];
if (pre[x]) {
ch[pre[y]][ch[pre[y]][1] == y] = x;
}
ch[x][f] = y;
pre[y] = x;
push_up(y);
}
void splay(int x, int goal) {
push_down(x);
while (pre[x] != goal) {
int y = pre[x], z = pre[y];
if (z == goal) {
push_down(y);
push_down(x);
rotate(x, ch[y][0] == x);
} else {
push_down(z);
push_down(y);
push_down(x);
int f = ch[z][0] == y;
if (ch[y][f] == x) {
rotate(x, f ^ 1);
} else {
rotate(y, f);
}
rotate(x, f);
}
}
push_up(x);
if (goal == 0) {
root = x;
}
}
void rotate_to(int k, int goal) {
int x = root;
push_down(x);
while (size[ch[x][0]] != k) {
if (k < size[ch[x][0]]) {
x = ch[x][0];
} else {
k -= size[ch[x][0]] + 1;
x = ch[x][1];
}
push_down(x);
}
splay(x, goal);
}
void erase(int x) {
int fa = pre[x], head = 0, tail = 0;
for (que[tail++] = x; head < tail; ++head) {
gc[tot2++] = que[head];
if (ch[que[head]][0]) {
que[tail++] = ch[que[head]][0];
}
if (ch[que[head]][1]) {
que[tail++] = ch[que[head]][1];
}
}
ch[fa][ch[fa][1] == x] = 0;
push_up(fa);
}
void new_node(int &x, int v, int fa) {
if (tot2) {
x = gc[--tot2];
} else {
x = ++tot1;
}
ch[x][0] = ch[x][1] = 0;
pre[x] = fa;
size[x] = 1;
key[x] = vmin[x] = v;
add[x] = rev[x] = 0;
}
void update_add(int x, int d) {
if (x) {
key[x] += d;
add[x] += d;
vmin[x] += d;
}
}
void update_rev(int x) {
if (x) {
swap(ch[x][0], ch[x][1]);
rev[x] ^= 1;
}
}
void push_up(int x) {
size[x] = size[ch[x][0]] + size[ch[x][1]] + 1;
vmin[x] = min(key[x], min(vmin[ch[x][0]], vmin[ch[x][1]]));
}
void push_down(int x) {
if (add[x]) {
update_add(ch[x][0], add[x]);
update_add(ch[x][1], add[x]);
add[x] = 0;
}
if (rev[x]) {
update_rev(ch[x][0]);
update_rev(ch[x][1]);
rev[x] = 0;
}
}
void build(int &x, int l, int r, int f) {
int m = l + r >> 1;
new_node(x, num[m], f);
if (l < m) {
build(ch[x][0], l, m - 1, x);
}
if (r > m) {
build(ch[x][1], m + 1, r, x);
}
push_up(x);
}
void init(int n) {
root = tot1 = tot2 = 0;
ch[0][0] = ch[0][1] = pre[0] = size[0] = 0;
add[0] = rev[0] = 0;
key[0] = vmin[0] = INF;
new_node(root, -1, 0);
new_node(ch[root][1], -1, root);
size[root] = 2;
for (int i = 1; i <= n; ++i) {
scanf("%d", &num[i]);
}
build(keyTree, 1, n, ch[root][1]);
push_up(ch[root][1]);
push_up(root);
}
void plus(int l, int r, int v) {
rotate_to(l - 1, 0);
rotate_to(r + 1, root);
update_add(keyTree, v);
}
void reverse(int l, int r) {
rotate_to(l - 1, 0);
rotate_to(r + 1, root);
update_rev(keyTree);
}
void revolve(int l, int r, int k) {
k %= r - l + 1;
if (!k) {
return;
}
rotate_to(r - k, 0);
rotate_to(r + 1, root);
int tmp = keyTree;
keyTree = 0;
push_up(ch[root][1]);
push_up(root);
rotate_to(l - 1, 0);
rotate_to(l, root);
keyTree = tmp;
pre[tmp] = ch[root][1];
push_up(ch[root][1]);
push_up(root);
}
void insert(int k, int v) {
rotate_to(k, 0);
rotate_to(k + 1, root);
new_node(keyTree, v, ch[root][1]);
push_up(ch[root][1]);
push_up(root);
}
void del(int k) {
rotate_to(k - 1, 0);
rotate_to(k + 1, root);
erase(keyTree);
push_up(ch[root][1]);
push_up(root);
}
int query(int l, int r) {
rotate_to(l - 1, 0);
rotate_to(r + 1, root);
return vmin[keyTree];
}
} splay;
int main() {
int n, m, x, y, v;
char op[10];
while (~scanf("%d", &n)) {
splay.init(n);
scanf("%d", &m);
while (m--) {
scanf("%s", op);
switch (op[0]) {
case 'A':
scanf("%d%d%d", &x, &y, &v);
splay.plus(x, y, v);
break;
case 'R':
scanf("%d%d", &x, &y);
if (op[3] == 'E') {
splay.reverse(x, y);
} else {
scanf("%d", &v);
splay.revolve(x, y, v);
}
break;
case 'I':
scanf("%d%d", &x, &v);
splay.insert(x, v);
break;
case 'D':
scanf("%d", &x);
splay.del(x);
break;
case 'M':
scanf("%d%d", &x, &y);
printf("%d\n", splay.query(x, y));
break;
}
}
}
}
//ver.2
int k1, k2, num[N];
struct Splay {
int root, tot, point;
int ch[N][2], pre[N], size[N];
int key[N], add[N], rev[N];
bool isroot(int x) { return !pre[x] || ch[pre[x]][0] != x && ch[pre[x]][1] != x; }
void rotate(int x) {
int y = pre[x], f = ch[y][1] == x;
ch[y][f] = ch[x][f ^ 1];
pre[ch[y][f]] = y;
if (!isroot(y)) { ch[pre[y]][ch[pre[y]][1] == y] = x; }
pre[x] = pre[y];
ch[x][f ^ 1] = y;
pre[y] = x;
push_up(y);
}
void splay(int x) {
push_down(x);
while (!isroot(x)) {
int y = pre[x], z = pre[y];
if (isroot(y)) {
push_down(y);
push_down(x);
rotate(x);
} else {
push_down(z);
push_down(y);
push_down(x);
rotate((ch[z][1] == y) == (ch[y][1] == x) ? y : x);
rotate(x);
}
}
push_up(x);
}
void new_node(int &x, int v, int fa) {
x = ++tot;
ch[x][0] = ch[x][1] = 0;
pre[x] = fa;
size[x] = 1;
key[x] = v;
add[x] = rev[x] = 0;
}
void update_add(int x, int v) {
if (x) { key[x] += v; add[x] += v; }
}
void update_rev(int x) {
if (x) { rev[x] ^= 1; swap(ch[x][0], ch[x][1]); }
}
void push_down(int x) {
if (add[x]) {
update_add(ch[x][0], add[x]);
update_add(ch[x][1], add[x]);
add[x] = 0;
}
if (rev[x]) {
update_rev(ch[x][0]);
update_rev(ch[x][1]);
rev[x] = 0;
}
}
void push_up(int x) { size[x] = size[ch[x][0]] + size[ch[x][1]] + 1; }
void build(int &x, int l, int r, int fa) {
int m = l + r >> 1;
new_node(x, num[m], fa);
if (l < m) { build(ch[x][0], l, m - 1, x); }
if (r > m) { build(ch[x][1], m + 1, r, x); }
push_up(x);
}
void init(int n) {
root = tot = size[0] = 0;
for (int i = 1; i <= n; ++i) {
scanf("%d", &num[i]);
}
build(root, 1, n, 0);
point = 1;
}
int find(int rt, int k) {
int x = rt;
while (size[ch[x][0]] + 1 != k) {
push_down(x);
if (k <= size[ch[x][0]]) {
x = ch[x][0];
} else {
k -= size[ch[x][0]] + 1;
x = ch[x][1];
}
}
return x;
}
void split(int &x, int &y, int sz) {
if (!sz) { y = x; x = 0; return; }
y = find(x, sz + 1);
splay(y);
x = ch[y][0];
ch[y][0] = 0;
push_up(y);
}
void split3(int &x, int &y, int &z, int l, int r) {
split(x, z, r); split(x, y, l - 1);
}
void join(int &x, int &y) {
if (!x || !y) { x |= y; return; }
x = find(x, size[x]);
splay(x);
ch[x][1] = y;
pre[y] = x;
push_up(x);
}
void join3(int &x, int y, int z) {
join(y, z); join(x, y);
}
void evert() {
if (point > 1) {
int x;
split(root, x, point - 1);
swap(root, x);
join(root, x);
point = 1;
}
}
void plus(int v) {
evert();
int x, y;
split3(root, x, y, point, point + k2 - 1);
update_add(x, v);
join3(root, x, y);
}
void reverse() {
evert();
int x, y;
split3(root, x, y, point, point + k1 - 1);
update_rev(x);
join3(root, x, y);
}
void insert(int v) {
evert();
int x, y;
split(root, x, point);
new_node(y, v, 0);
join3(root, y, x);
}
void erase() {
evert();
int x, y;
split3(root, x, y, point, point);
join(root, y);
}
void move(int tag) {
switch (tag) {
case 1:
if (--point == 0) { point = size[root]; }
break;
case 2:
if (++point == size[root] + 1) { point = 1; }
break;
}
}
void query() {
evert();
int x, y;
split3(root, x, y, point, point);
printf("%d\n", key[x]);
join3(root, x, y);
}
} splay;
//HDU4453
int main() {
int n, m, v, cas = 0;
char op[10];
while (~scanf("%d%d%d%d", &n, &m, &k1, &k2) && (n || m || k1 || k2)) {
splay.init(n);
printf("Case #%d:\n", ++cas);
while (m--) {
scanf("%s", op);
switch (op[0]) {
case 'a':
scanf("%d", &v);
splay.plus(v);
break;
case 'r':
splay.reverse();
break;
case 'i':
scanf("%d", &v);
splay.insert(v);
break;
case 'd':
splay.erase();
break;
case 'm':
scanf("%d", &v);
splay.move(v);
break;
case 'q':
splay.query();
break;
}
}
}
}
//ver.3
const int N = 500005;
const int INF = 0x3f3f3f3f;
int n, q;
struct Splay {
int pre[N], ch[N][2], key[N], size[N];
int root, tot1;
int sum[N], rev[N], same[N];
int lx[N], rx[N], mx[N];
int s[N], tot2; //<2F>ڴ<EFBFBD><DAB4>غ<EFBFBD><D8BA><EFBFBD><EFBFBD><EFBFBD>
int a[N];
void NewNode(int &r, int father, int k) {
if (tot2) { r = s[tot2--]; } //ȡ<><C8A1>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>tot2--,<2C><><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>++tot2
else { r = ++tot1; }
pre[r] = father;
ch[r][0] = ch[r][1] = 0;
key[r] = k;
sum[r] = k;
rev[r] = same[r] = 0;
lx[r] = rx[r] = mx[r] = k;
size[r] = 1;
}
void Update_Rev(int r) {
if (!r) { return; }
swap(ch[r][0], ch[r][1]);
swap(lx[r], rx[r]);
rev[r] ^= 1;
}
void Update_Same(int r, int v) {
if (!r) { return; }
key[r] = v;
sum[r] = v * size[r];
lx[r] = rx[r] = mx[r] = max(v, v * size[r]);
same[r] = 1;
}
void push_up(int r) {
int lson = ch[r][0], rson = ch[r][1];
size[r] = size[lson] + size[rson] + 1;
sum[r] = sum[lson] + sum[rson] + key[r];
lx[r] = max(lx[lson], sum[lson] + key[r] + max(0, lx[rson]));
rx[r] = max(rx[rson], sum[rson] + key[r] + max(0, rx[lson]));
mx[r] = max(0, rx[lson]) + key[r] + max(0, lx[rson]);
mx[r] = max(mx[r], max(mx[lson], mx[rson]));
}
void push_down(int r) {
if (same[r]) {
Update_Same(ch[r][0], key[r]);
Update_Same(ch[r][1], key[r]);
same[r] = 0;
}
if (rev[r]) {
Update_Rev(ch[r][0]);
Update_Rev(ch[r][1]);
rev[r] = 0;
}
}
void Build(int &x, int l, int r, int father) {
if (l > r) { return; }
int mid = (l + r) / 2;
NewNode(x, father, a[mid]);
Build(ch[x][0], l, mid - 1, x);
Build(ch[x][1], mid + 1, r, x);
push_up(x);
}
void Init() {
root = tot1 = tot2 = 0;
ch[root][0] = ch[root][1] = size[root] = pre[root] = 0;
same[root] = rev[root] = sum[root] = key[root] = 0;
lx[root] = rx[root] = mx[root] = -INF;
NewNode(root, 0, -1);
NewNode(ch[root][1], root, -1);
for (int i = 0; i < n; i++) {
scanf("%d", &a[i]);
}
Build(ch[ch[root][1]][0], 0, n - 1, ch[root][1]);
push_up(ch[root][1]);
push_up(root);
}
//<2F><>ת,0Ϊ<30><CEAA><EFBFBD><EFBFBD>, 1Ϊ<31><CEAA><EFBFBD><EFBFBD>
void Rotate(int x, int kind) {
int y = pre[x];
push_down(y);
push_down(x);
ch[y][!kind] = ch[x][kind];
pre[ch[x][kind]] = y;
if (pre[y]) { ch[pre[y]][ch[pre[y]][1] == y] = x; }
pre[x] = pre[y];
ch[x][kind] = y;
pre[y] = x;
push_up(y);
}
//Splay<61><79><EFBFBD><EFBFBD>, <20><>r<EFBFBD><72><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>goal<61><6C><EFBFBD><EFBFBD>
void Splay(int r, int goal) {
push_down(r);
while (pre[r] != goal) {
if (pre[pre[r]] == goal) {
push_down(pre[r]);
push_down(r);
Rotate(r, ch[pre[r]][0] == r);
} else {
push_down(pre[pre[r]]);
push_down(pre[r]);
push_down(r);
int y = pre[r];
int kind = ch[pre[y]][0] == y;
if (ch[y][kind] == r) {
Rotate(r, !kind);
Rotate(r, kind);
} else {
Rotate(y, kind);
Rotate(r, kind);
}
}
}
push_up(r);
if (goal == 0) { root = r; }
}
int Get_kth(int r, int k) {
push_down(r);
int t = size[ch[r][0]] + 1;
if (t == k) { return r; }
if (t > k) { return Get_kth(ch[r][0], k); }
else { return Get_kth(ch[r][1], k - t); }
}
//<2F>ڵ<EFBFBD>pos<6F><73><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>tot<6F><74><EFBFBD><EFBFBD>
void Insert(int pos, int tot) {
for (int i = 0; i < tot; i++) { scanf("%d", &a[i]); }
Splay(Get_kth(root, pos + 1), 0);
Splay(Get_kth(root, pos + 2), root);
Build(ch[ch[root][1]][0], 0, tot - 1, ch[root][1]);
push_up(ch[root][1]);
push_up(root);
}
//ɾ<><C9BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void erase(int r) {
if (!r) { return; }
s[++tot2] = r;
erase(ch[r][0]);
erase(ch[r][1]);
}
//<2F>ӵ<EFBFBD>pos<6F><73><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>ɾ<EFBFBD><C9BE>tot<6F><74><EFBFBD><EFBFBD>
void Delete(int pos, int tot) {
Splay(Get_kth(root, pos), 0);
Splay(Get_kth(root, pos + tot + 1), root);
erase(ch[ch[root][1]][0]);
pre[ch[ch[root][1]][0]] = 0;
ch[ch[root][1]][0] = 0;
push_up(ch[root][1]);
push_up(root);
}
//<2F><><EFBFBD>ӵ<EFBFBD>pos<6F><73><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>tot<6F><74><EFBFBD><EFBFBD><EFBFBD>޸<EFBFBD>Ϊc
void Make_Same(int pos, int tot, int c) {
Splay(Get_kth(root, pos), 0);
Splay(Get_kth(root, pos + tot + 1), root);
Update_Same(ch[ch[root][1]][0], c);
push_up(ch[root][1]);
push_up(root);
}
//<2F><><EFBFBD><EFBFBD>pos<6F><73><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>tot<6F><74><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>з<EFBFBD>ת
void Reverse(int pos, int tot) {
Splay(Get_kth(root, pos), 0);
Splay(Get_kth(root, pos + tot + 1), root);
Update_Rev(ch[ch[root][1]][0]);
push_up(ch[root][1]);
push_up(root);
}
//<2F>õ<EFBFBD><C3B5><EFBFBD>pos<6F><73><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC>tot<6F><74><EFBFBD><EFBFBD><EFBFBD>ĺ<EFBFBD>
int Get_Sum(int pos, int tot) {
Splay(Get_kth(root, pos), 0);
Splay(Get_kth(root, pos + tot + 1), root);
return sum[ch[ch[root][1]][0]];
}
//<2F>õ<EFBFBD><C3B5><EFBFBD>pos<6F><73><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC>tot<6F><74><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӷκ<D3B6>
int Get_MaxSum(int pos, int tot) {
Splay(Get_kth(root, pos), 0);
Splay(Get_kth(root, pos + tot + 1), root);
return mx[ch[ch[root][1]][0]];
}
void InOrder(int r) {
if (!r) { return; }
push_down(r);
InOrder(ch[r][0]);
printf("%d ", key[r]);
InOrder(ch[r][1]);
}
} splay;
int main() {
while (scanf("%d%d", &n, &q) == 2) {
splay.Init();
char op[20];
int x, y, z;
while (q--) {
scanf("%s", op);
if (strcmp(op, "INSERT") == 0) {
scanf("%d%d", &x, &y);
splay.Insert(x, y);
} else if (strcmp(op, "DELETE") == 0) {
scanf("%d%d", &x, &y);
splay.Delete(x, y);
} else if (strcmp(op, "MAKE-SAME") == 0) {
scanf("%d%d%d", &x, &y, &z);
splay.Make_Same(x, y, z);
} else if (strcmp(op, "REVERSE") == 0) {
scanf("%d%d", &x, &y);
splay.Reverse(x, y);
} else if (strcmp(op, "GET-SUM") == 0) {
scanf("%d%d", &x, &y);
printf("%d\n", splay.Get_Sum(x, y));
} else if (strcmp(op, "MAX-SUM") == 0) {
printf("%d\n", splay.Get_MaxSum(1, splay.size[root] - 2));
}
}
}
}
//Link-Cut Tree <20><>̬<EFBFBD><CCAC>
//ά<><CEAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><><C9AD>)<29><><EFBFBD><EFBFBD>̬, <20><><EFBFBD><EFBFBD>O(logn)<29><>ʱ<EFBFBD><EFBFBD>Ӷ<EFBFBD><D3B6><EFBFBD>ά<EFBFBD><CEAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ; <20><>LCT<43><54><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD><EFBFBD>dz<EFBFBD><C7B3>鷳.
//<2F><><EFBFBD>ĺ<EFBFBD><C4BA>IJ<EFBFBD><C4B2><EFBFBD><EFBFBD><EFBFBD>access<73><73><EFBFBD><EFBFBD>, <20><><EFBFBD>԰<EFBFBD>ij<EFBFBD><C4B3><EFBFBD>ڵ㵽<DAB5><E3B5BD><EFBFBD><EFBFBD>·<EFBFBD><C2B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>е<D0B5><E3B0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Splayά<79><CEAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,
//<2F>Ӷ<EFBFBD><D3B6><EFBFBD><EFBFBD><EFBFBD>evert<72><74><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)<29><>splay<61><79><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD>ֶ<EFBFBD><D6B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣά<CFA2><CEAC>.
//LCT<43><54><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD>ֳ<EFBFBD>ά<EFBFBD><CEAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD><EFBFBD>ϵ<EFBFBD><CFB5><EFBFBD><EFBFBD>в<EFBFBD><D0B2><EFBFBD>, ͬʱ<CDAC><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Խ<EFBFBD><D4BD><EFBFBD><EFBFBD><EFBFBD>۸<EFBFBD><DBB8>Ӷ<EFBFBD>,
//<2F><>ʵ<EFBFBD>ʳ<EFBFBD><CAB3><EFBFBD><EFBFBD>ϴ<EFBFBD>, <20>ܶ಻<DCB6>ı<EFBFBD><C4B1><EFBFBD><EFBFBD><EFBFBD>̬<EFBFBD><CCAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>O(logn)<29><>LCT<43><54><EFBFBD><EFBFBD><EFBFBD><EFBFBD>O(log^2n)<29><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʷ<EFBFBD><CAB7><EFBFBD><EFBFBD>߶<EFBFBD><DFB6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Խ
struct LCT {
int ch[N][2], pre[N], key[N], rev[N];
int add[N], vmax[N];
bool isroot(int x) { return !pre[x] || ch[pre[x]][0] != x && ch[pre[x]][1] != x; }
void rotate(int x) {
int y = pre[x], f = ch[y][1] == x;
ch[y][f] = ch[x][f ^ 1];
pre[ch[y][f]] = y;
if (!isroot(y)) { ch[pre[y]][ch[pre[y]][1] == y] = x; }
pre[x] = pre[y];
ch[x][f ^ 1] = y;
pre[y] = x;
push_up(y);
}
void splay(int x) {
push_down(x);
while (!isroot(x)) {
int y = pre[x], z = pre[y];
if (isroot(y)) {
push_down(y);
push_down(x);
rotate(x);
} else {
push_down(z);
push_down(y);
push_down(x);
rotate((ch[z][1] == y) == (ch[y][1] == x) ? y : x);
rotate(x);
}
}
push_up(x);
}
int access(int x) {
int y = 0;
for (; x; x = pre[x]) {
splay(x);
ch[x][1] = y;
push_up(x);
y = x;
}
return y;
}
void evert(int x) {
rev[access(x)] ^= 1;
splay(x);
}
void push_up(int x) { vmax[x] = max(max(vmax[ch[x][0]], vmax[ch[x][1]]), key[x]); }
void push_down(int x) {
if (add[x]) {
key[x] += add[x];
if (ch[x][0]) {
add[ch[x][0]] += add[x];
vmax[ch[x][0]] += add[x];
}
if (ch[x][1]) {
add[ch[x][1]] += add[x];
vmax[ch[x][1]] += add[x];
}
add[x] = 0;
}
if (rev[x]) {
if (ch[x][0]) { rev[ch[x][0]] ^= 1; }
if (ch[x][1]) { rev[ch[x][1]] ^= 1; }
swap(ch[x][0], ch[x][1]);
rev[x] = 0;
}
}
int find_root(int x) {
while (pre[x]) { x = pre[x]; }
return x;
}
//<2F><><EFBFBD><EFBFBD>u,v<><76><EFBFBD><EFBFBD>ͬһ<CDAC><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<2C><>ͨ<EFBFBD><CDA8><EFBFBD><EFBFBD>u,v֮<76><D6AE><EFBFBD><EFBFBD><EFBFBD>ߵķ<DFB5>ʽ,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void link(int u, int v) {
if (find_root(u) == find_root(v)) { puts("-1"); return; }
evert(u);
pre[u] = v;
}
//<2F><><EFBFBD><EFBFBD>u,v<><76>ͬһ<CDAC><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<2C><>u!=v,<2C><><EFBFBD><EFBFBD>u<EFBFBD><75>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĸ<EFBFBD><C4B8>Ժ<EFBFBD>,<2C>ж<EFBFBD>v<EFBFBD><76><EFBFBD><EFBFBD>׽<EFBFBD><D7BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void cut(int u, int v) {
if (u == v || find_root(u) != find_root(v)) { puts("-1"); return; }
evert(u);
access(v);
splay(v);
pre[ch[v][0]] = 0;
ch[v][0] = 0;
push_up(v);
}
//<2F><><EFBFBD><EFBFBD>u,v<><76>ͬһ<CDAC><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<2C><><EFBFBD><EFBFBD>u,v֮<76><D6AE>·<EFBFBD><C2B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>е<EFBFBD><D0B5>ĵ<EFBFBD>Ȩ<EFBFBD><C8A8><EFBFBD><EFBFBD>w
void update(int u, int v, int w) {
if (find_root(u) != find_root(v)) { puts("-1"); return; }
evert(u);
access(v);
splay(v);
add[v] += w;
vmax[v] += w;
push_down(v);
}
//<2F><><EFBFBD><EFBFBD>u,v<><76>ͬһ<CDAC><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD>u,v֮<76><D6AE>·<EFBFBD><C2B7><EFBFBD>ϵ<EFBFBD>Ȩ<EFBFBD><C8A8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ
void query(int u, int v) {
if (find_root(u) != find_root(v)) { puts("-1"); return; }
evert(u);
access(v);
splay(v);
printf("%d\n", vmax[v]);
}
struct graph {
int head[N], to[N << 1], next[N << 1];
int tot;
void init() { tot = 0; memset(head, 0xff, sizeof(head)); }
void add(int u, int v) {
to[tot] = v;
next[tot] = head[u];
head[u] = tot++;
}
} g;
void dfs(int u, int fa) {
for (int i = g.head[u]; ~i; i = g.next[i]) {
int v = g.to[i];
if (v != fa) {
dfs(v, u);
pre[v] = u;
}
}
}
void init(int n) {
int m, x, y;
g.init();
for (int i = 1; i < n; ++i) {
scanf("%d%d", &x, &y);
g.add(x, y); g.add(y, x);
}
memset(ch, 0, sizeof(ch));
memset(pre, 0, sizeof(pre));
memset(rev, 0, sizeof(rev));
memset(add, 0, sizeof(add));
vmax[0] = 0;
for (int i = 1; i <= n; ++i) {
scanf("%d", &key[i]);
vmax[i] = key[i];
}
dfs(1, 0);
}
} lct;
//HDU4010
int main() {
int n, q, op, x, y, w;
while (~scanf("%d", &n)) {
lct.init(n);
scanf("%d", &q);
while (q--) {
scanf("%d", &op);
switch (op) {
case 1:
scanf("%d%d", &x, &y);
lct.link(x, y);
break;
case 2:
scanf("%d%d", &x, &y);
lct.cut(x, y);
break;
case 3:
scanf("%d%d%d", &w, &x, &y);
lct.update(x, y, w);
break;
case 4:
scanf("%d%d", &x, &y);
lct.query(x, y);
break;
}
}
putchar('\n');
}
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ת<EFBFBD><D7AA>Treap
int num[N];
struct Treap {
int tot, root;
int ch[N][2], pt[N], size[N];
int key[N], vmin[N], add[N], rev[N];
void init() { tot = 0; }
void new_node(int &x, int v) {
x = ++tot;
ch[x][0] = ch[x][1] = 0;
size[x] = 1;
pt[x] = rand();
key[x] = vmin[x] = v;
add[x] = rev[x] = 0;
}
void merge(int &p, int x, int y) {
if (!x || !y) { p = x | y; return; }
if (pt[x] < pt[y]) {
push_down(x);
merge(ch[x][1], ch[x][1], y);
p = x;
} else {
push_down(y);
merge(ch[y][0], x, ch[y][0]);
p = y;
}
push_up(p);
}
void split(int p, int sz, int &x, int &y) {
if (!sz) { x = 0; y = p; return; }
push_down(p);
if (size[ch[p][0]] >= sz) {
y = p;
split(ch[p][0], sz, x, ch[y][0]);
} else {
x = p;
split(ch[p][1], sz - size[ch[p][0]] - 1, ch[x][1], y);
}
push_up(p);
}
void update_add(int x, int v) {
if (x) { key[x] += v; add[x] += v; vmin[x] += v; }
}
void update_rev(int x) {
if (x) { swap(ch[x][0], ch[x][1]); rev[x] ^= 1; }
}
void push_down(int x) {
if (add[x]) {
update_add(ch[x][0], add[x]);
update_add(ch[x][1], add[x]);
add[x] = 0;
}
if (rev[x]) {
update_rev(ch[x][0]);
update_rev(ch[x][1]);
rev[x] = 0;
}
}
void push_up(int x) {
size[x] = 1;
vmin[x] = key[x];
if (ch[x][0]) {
size[x] += size[ch[x][0]];
vmin[x] = min(vmin[x], vmin[ch[x][0]]);
}
if (ch[x][1]) {
size[x] += size[ch[x][1]];
vmin[x] = min(vmin[x], vmin[ch[x][1]]);
}
}
int build(int &x, int l, int r) {
int m = l + r >> 1;
new_node(x, num[m]);
if (l < m) { build(ch[x][0], l, m - 1); }
if (r > m) { build(ch[x][1], m + 1, r); }
push_up(x);
}
void plus(int l, int r, int v) {
int x, y;
split(root, l - 1, root, x);
split(x, r - l + 1, x, y);
update_add(x, v);
merge(x, x, y);
merge(root, root, x);
}
void reverse(int l, int r) {
int x, y;
split(root, l - 1, root, x);
split(x, r - l + 1, x, y);
update_rev(x);
merge(x, x, y);
merge(root, root, x);
}
void revolve(int l, int r, int k) {
int x, y, p, q;
k %= r - l + 1;
if (!k) { return; }
split(root, l - 1, root, x);
split(x, r - l + 1, x, y);
split(x, r - l + 1 - k, p, q);
merge(x, q, p);
merge(x, x, y);
merge(root, root, x);
}
void insert(int k, int v) {
int x, y;
new_node(x, v);
split(root, k, root, y);
merge(root, root, x);
merge(root, root, y);
}
void erase(int k) {
int x, y;
split(root, k - 1, root, x);
split(x, 1, x, y);
merge(root, root, y);
}
int query(int l, int r) {
int x, y, ret;
split(root, l - 1, root, x);
split(x, r - l + 1, x, y);
ret = vmin[x];
merge(x, x, y);
merge(root, root, x);
return ret;
}
} treap;
//POJ3580
int main() {
int n, m, x, y, v;
char op[10];
while (~scanf("%d", &n)) {
treap.init();
for (int i = 1; i <= n; ++i) {
scanf("%d", &num[i]);
}
treap.build(treap.root, 1, n);
scanf("%d", &m);
while (m--) {
scanf("%s", op);
switch (op[0]) {
case 'A':
scanf("%d%d%d", &x, &y, &v);
treap.plus(x, y, v);
break;
case 'R':
scanf("%d%d", &x, &y);
if (op[3] == 'E') {
treap.reverse(x, y);
} else {
scanf("%d", &v);
treap.revolve(x, y, v);
}
break;
case 'I':
scanf("%d%d", &x, &v);
treap.insert(x, v);
break;
case 'D':
scanf("%d", &x);
treap.erase(x);
break;
case 'M':
scanf("%d%d", &x, &y);
printf("%d\n", treap.query(x, y));
break;
}
}
}
}
//<2F>ɳ־û<D6BE>Treap
const int N = 50005;
const int M = 5000005;
int root[N], vs, d;
struct Treap {
int tot;
int ch[M][2], size[M];
char key[M];
bool hey(int x, int y) { return (ll)rand() * (size[x] + size[y]) < (ll)size[x] * RAND_MAX; }
void init() { tot = 0; }
void new_node(int &x, char v) {
x = ++tot;
ch[x][0] = ch[x][1] = 0;
size[x] = 1;
key[x] = v;
}
void copy_node(int &x, int y) {
if (!y) { x = 0; return; }
x = ++tot;
ch[x][0] = ch[y][0];
ch[x][1] = ch[y][1];
size[x] = size[y];
key[x] = key[y];
}
void merge(int &p, int x, int y) {
if (!x || !y) {
p = 0;
if (x) { copy_node(p, x); }
if (y) { copy_node(p, y); }
return;
}
if (hey(x, y)) {
copy_node(p, x);
merge(ch[p][1], ch[x][1], y);
} else {
copy_node(p, y);
merge(ch[p][0], x, ch[y][0]);
}
push_up(p);
}
void split(int p, int sz, int &x, int &y) {
if (!sz) { x = 0; copy_node(y, p); return; }
if (size[ch[p][0]] >= sz) {
copy_node(y, p);
split(ch[p][0], sz, x, ch[y][0]);
push_up(y);
} else {
copy_node(x, p);
split(ch[p][1], sz - size[ch[p][0]] - 1, ch[x][1], y);
push_up(x);
}
}
void push_up(int x) {
size[x] = 1;
if (ch[x][0]) { size[x] += size[ch[x][0]]; }
if (ch[x][1]) { size[x] += size[ch[x][1]]; }
}
void build(char str[], int &x, int l, int r) {
int m = l + r >> 1;
new_node(x, str[m]);
if (l < m) { build(str, ch[x][0], l, m - 1); }
if (r > m) { build(str, ch[x][1], m + 1, r); }
push_up(x);
}
void insert(int k, char str[]) {
int x, y, z;
build(str, x, 0, strlen(str) - 1);
split(root[vs], k, y, z);
merge(y, y, x);
merge(root[++vs], y, z);
}
void erase(int k, int sz) {
int x, y, z;
split(root[vs], k - 1, x, y);
split(y, sz, y, z);
merge(root[++vs], x, z);
}
void output(int x) {
if (ch[x][0]) { output(ch[x][0]); }
putchar(key[x]);
d += key[x] == 'c';
if (ch[x][1]) { output(ch[x][1]); }
}
void output(int v, int k, int sz) {
int x, y, z;
split(root[v], k - 1, x, y);
split(y, sz, y, z);
output(y);
putchar('\n');
}
} treap;
//UVa12538
int main() {
int n, op, p, c, v;
char s[105];
treap.init();
vs = d = 0;
scanf("%d", &n);
while (n--) {
scanf("%d", &op);
switch (op) {
case 1:
scanf("%d%s", &p, s);
treap.insert(p - d, s);
break;
case 2:
scanf("%d%d", &p, &c);
treap.erase(p - d, c - d);
break;
case 3:
scanf("%d%d%d", &v, &p, &c);
treap.output(v - d, p - d, c - d);
break;
}
}
}
//<2F><><EFBFBD><EFBFBD><EFBFBD>ʷ<EFBFBD>
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʷֽ<CAB7>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֳ<EFBFBD><D6B3><EFBFBD><EFBFBD><EFBFBD>logn<67><6E><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD>ÿ<EFBFBD><C3BF><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,
//<2F>Ӷ<EFBFBD><D3B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><C2B7><EFBFBD>޸<EFBFBD>ת<EFBFBD><D7AA>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD>logn<67><6E><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>޸<EFBFBD>, <20>dz<EFBFBD><C7B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>״<EFBFBD><D7B4><EFBFBD><EFBFBD>߶<EFBFBD><DFB6><EFBFBD><EFBFBD>ȸ<EFBFBD><C8B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݽṹ.
//<2F><><EFBFBD><EFBFBD><EFBFBD>ʷֵij<D6B5><C4B3><EFBFBD><EFBFBD><EFBFBD>С, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʷֵ<CAB7><D6B5><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD>Խ<EFBFBD><D4BD><EFBFBD>˻<EFBFBD><CBBB><EFBFBD><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>³<EFBFBD>Ϊһ<CEAA><D2BB><EFBFBD><EFBFBD>),
//<2F><><EFBFBD><EFBFBD><EFBFBD>ʷֵ<CAB7>Ч<EFBFBD><D0A7>Խ<EFBFBD>Ǻ<EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>O(1)<29><><EFBFBD><EFBFBD>, <20><>Ϊֻ<CEAA>к<EFBFBD><D0BA>ٵ<EFBFBD><D9B5><EFBFBD><EFBFBD><EFBFBD>),
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һЩ<D2BB><D0A9><EFBFBD><EFBFBD><E6BCB0>̬<EFBFBD>޸ĵ<DEB8><C4B5><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><C2B7>ά<EFBFBD><CEAC><EFBFBD><EFBFBD>Ŀ, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʷ<EFBFBD><CAB7><EFBFBD><EFBFBD>߶<EFBFBD><DFB6><EFBFBD><EFBFBD><EFBFBD>O(logn^2)<29>ĵ<EFBFBD><C4B5>β<EFBFBD><CEB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӷ<EFBFBD>ˮ<EFBFBD><CBAE>,
//<2F><>ʵ<EFBFBD>ʱ<EFBFBD><CAB1>ֲ<EFBFBD><D6B2><EFBFBD><EFBFBD>ڵ<EFBFBD><DAB5>β<EFBFBD><CEB2><EFBFBD>O(logn)<29><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܴ<EFBFBD><DCB4><EFBFBD>LCT.
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʷֵij<D6B5>ʼ<EFBFBD><CABC>ʵ<EFBFBD><CAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>dfs<66><73>, <20><>dfs<66><73><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,
//һ<>ǵݹ<C7B5><DDB9><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Щ<EFBFBD><D0A9>Ŀ<EFBFBD>б<EFBFBD>ջ<EFBFBD><D5BB><EFBFBD><EFBFBD>; <20><><EFBFBD><EFBFBD><EFBFBD>ҳ<EFBFBD><D2B3><EFBFBD>bfsʵ<73>ֵĺܺ<C4BA><DCBA>õĽ<C3B5><C4BD><EFBFBD><EFBFBD><EFBFBD>.
//<2F><>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD>˵<EFBFBD><CBB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD>ڵ<EFBFBD>Ȩ<EFBFBD>޸<EFBFBD>ֱ<EFBFBD><D6B1>ά<EFBFBD><CEAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD>ڱ<EFBFBD>Ȩ<EFBFBD>޸<EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѡ<EFBFBD><D1A1>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>,
//<2F><><EFBFBD><EFBFBD>Ȩ<EFBFBD>´<EFBFBD><C2B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȸ<EFBFBD><C8B8><EFBFBD><EFBFBD>Ľڵ<C4BD><DAB5><EFBFBD>; <20><><EFBFBD><EFBFBD>֮, ÿ<><C3BF><EFBFBD><EFBFBD><E3B4A2><EFBFBD><EFBFBD>Ȩֵ<C8A8><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĸ<EFBFBD><C4B8>ڵ<EFBFBD>֮<EFBFBD><D6AE><EFBFBD>ı<EFBFBD>Ȩ, <20><><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD>û<EFBFBD><C3BB>Ȩֵ.
int top[N]; //top[p]<5D><>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD>Ϊp<CEAA><70>·<EFBFBD><C2B7><EFBFBD>Ķ<EFBFBD><C4B6>˽ڵ<CBBD>
int len[N]; //len[p]<5D><>ʾ·<CABE><C2B7>p<EFBFBD>ij<EFBFBD><C4B3><EFBFBD>
int belong[N]; //belong[v]<5D><>ʾ<EFBFBD>ڵ<EFBFBD>v<EFBFBD><76><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><C2B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
int idx[N]; //idx[v]<5D><>ʾ<EFBFBD>ڵ<EFBFBD>v<EFBFBD><76><EFBFBD><EFBFBD>·<EFBFBD><C2B7><EFBFBD>еı<D0B5><C4B1><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>dz<EEB5BD><C7B3><EFBFBD>α<EFBFBD><CEB1><EFBFBD>
int dep[N]; //dep[v]<5D><>ʾ<EFBFBD>ڵ<EFBFBD>v<EFBFBD><76><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
int fa[N]; //fa[v]<5D><>ʾ<EFBFBD>ڵ<EFBFBD>v<EFBFBD>ĸ<EFBFBD><C4B8>׽ڵ<D7BD>
int size[N]; //size[v]<5D><>ʾ<EFBFBD>Խڵ<D4BD><76><CEAA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ľڵ<C4BD><DAB5><EFBFBD><EFBFBD><EFBFBD>
int que[N];
bool vis[N];
int n, cnt; //n<>ǵ<EFBFBD><C7B5><EFBFBD>, <20><><EFBFBD>Ŵ<EFBFBD>1<EFBFBD><31>n
void split() {
memset(dep, 0xff, sizeof(dep));
int l = 0, r = 0;
que[++r] = 1; dep[1] = 0; fa[1] = -1;
while (l < r) {
int u = que[++l];
vis[u] = false;
for (int i = g.head[u]; ~i; i = g.next[i]) {
int v = g.to[i];
if (!~dep[v]) { que[++r] = v; dep[v] = dep[u] + 1; fa[v] = u; }
}
}
cnt = 0;
for (int i = n; i > 0; --i) {
int u = que[i], p = -1;
size[u] = 1;
for (int j = g.head[u]; ~j; j = g.next[j]) {
int v = g.to[j];
if (vis[v]) {
size[u] += size[v];
if (!~p || size[v] > size[p]) { p = v; }
}
}
if (!~p) {
idx[u] = len[++cnt] = 1;
belong[u] = cnt;
top[cnt] = u;
} else {
belong[u] = belong[p];
idx[u] = ++len[belong[u]];
top[belong[u]] = u;
}
vis[u] = true;
}
}
int fi[N], cid[N], rank[N];
void getcid() {
fi[1] = 1;
for (int i = 2; i <= cnt; ++i) { fi[i] = fi[i - 1] + len[i - 1]; }
for (int i = 1; i <= n; ++i) {
cid[i] = fi[belong[i]] + len[belong[i]] - idx[i];
rank[cid[i]] = i;
}
}
// ·<><C2B7><EFBFBD>޸ĺͲ<C4BA>ѯ<EFBFBD><D1AF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>޸<EFBFBD>
int query(int x, int y) {
int ret = 0;
while (belong[x] != belong[y]) {
if (dep[top[belong[x]]] < dep[top[belong[y]]]) { swap(x, y); }
ret = max(ret, query(cid[top[belong[x]]], cid[x], 1, n, 1));
x = fa[top[belong[x]]];
}
if (dep[x] > dep[y]) { swap(x, y); }
ret = max(ret, query(cid[x], cid[y], 1, n, 1));
/*<2A><>Ȩ<EFBFBD><C8A8><EFBFBD><EFBFBD>
if(x!=y)
ret=max(ret,query(cid[x]+1,cid[y],1,n,1));
*/
return ret;
}
//<2F><>һ<EFBFBD><D2BB>dfs<66>ͱ<EFBFBD><CDB1><EFBFBD>LCA<43><41>dfs<66><73><EFBFBD>ּ<EFBFBD><D6BC><EFBFBD>һ<EFBFBD><D2BB>; <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>޸ľͿ<C4BE><CDBF><EFBFBD><EFBFBD>޷<EFBFBD><DEB7>ν<EFBFBD>LCA.
//<2F>ڶ<EFBFBD><DAB6><EFBFBD>dfs<66>Խڵ<D4BD><DAB5><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD>ý<EFBFBD><C3BD><EFBFBD><EFBFBD>˱<EFBFBD><CBB1><EFBFBD>(<28><>Ӧbfs<66><73>getcid<69><64><EFBFBD><EFBFBD>),
//<2F><><EFBFBD>ǿ<EFBFBD><C7BF>Է<EFBFBD><D4B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˳<EFBFBD><CBB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>dfs(<28><>dfs<66>ض<EFBFBD><D8B6><EFBFBD><EFBFBD><EFBFBD>dfs<66><73><EFBFBD><EFBFBD><EFBFBD>ӽڵ<D3BD>), <20>õ<EFBFBD><C3B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>dfs<66><73>.
//<2F><><EFBFBD>仰˵, <20><><EFBFBD><EFBFBD><EFB4A6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʷֱ<CAB7><D6B1><EFBFBD>, ͬʱҲ<CAB1><D2B2>dfs<66><73><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
//<2F><><EFBFBD><EFBFBD>֪<EFBFBD><D6AA>ÿ<EFBFBD><C3BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ľڵ<C4BD><DAB5><EFBFBD>dfs<66><73><EFBFBD>ж<EFBFBD><D0B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>,
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǾͿ<C7BE><CDBF><EFBFBD>ͬʱά<CAB1><CEAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><C2B7><EFBFBD><EFBFBD>Ϣ(<28>ʷֲ<CAB7><D6B2>ָ<EFBFBD><D6B8>Ӷ<EFBFBD>O(logn))<29><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ(<28>ʷֲ<CAB7><D6B2>ָ<EFBFBD><D6B8>Ӷ<EFBFBD>O(1))<29><>.
//BZOJ3083 <20><><EFBFBD><EFBFBD><EFBFBD>ʷ<EFBFBD><CAB7><EFBFBD><EFBFBD>߶<EFBFBD><DFB6><EFBFBD>
const int N = 100005;
const int maxd = 18;
const int INF = 0x7fffffff;
struct graph {
int head[N], tot;
int to[N << 1], next[N << 1];
void init() {
tot = 0; memset(head, 0xff, sizeof(head));
}
void add(int u, int v) {
to[tot] = v; next[tot] = head[u]; head[u] = tot++;
}
} g;
int top[N], son[N];
int dep[N], fa[N][maxd], size[N];
int cid[N], rank[N], cnt;
void dfs1(int u) {
size[u] = 1; son[u] = -1;
for (int i = 1; i < maxd; ++i) { fa[u][i] = fa[fa[u][i - 1]][i - 1]; }
for (int i = g.head[u]; ~i; i = g.next[i]) {
int v = g.to[i];
if (v != fa[u][0]) {
dep[v] = dep[u] + 1; fa[v][0] = u;
dfs1(v);
size[u] += size[v];
if (!~son[u] || size[v] > size[son[u]]) { son[u] = v; }
}
}
}
void dfs2(int u, int tp) {
top[u] = tp; cid[u] = ++cnt; rank[cid[u]] = u;
if (~son[u]) { dfs2(son[u], tp); }
for (int i = g.head[u]; ~i; i = g.next[i]) {
int v = g.to[i];
if (v != son[u] && v != fa[u][0]) { dfs2(v, v); }
}
}
void split() {
dfs1(1); cnt = 0; dfs2(1, 1);
}
int lca(int u, int v) {
if (dep[u] < dep[v]) { swap(u, v); }
int k = dep[u] - dep[v];
for (int i = 0; i < maxd; ++i) {
if ((1 << i)&k) { u = fa[u][i]; }
}
if (u == v) { return u; }
for (int i = maxd - 1; i >= 0; --i) {
if (fa[u][i] != fa[v][i]) { u = fa[u][i]; v = fa[v][i]; }
}
return fa[u][0];
}
int n, root, a[N];
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
int vmin[N << 2], col[N << 2];
void push_up(int rt) {
vmin[rt] = min(vmin[rt << 1], vmin[rt << 1 | 1]);
}
void push_down(int rt) {
if (col[rt]) {
col[rt << 1] = col[rt << 1 | 1] = vmin[rt << 1] = vmin[rt << 1 | 1] = col[rt];
col[rt] = 0;
}
}
void build(int l, int r, int rt) {
col[rt] = 0;
if (l == r) { vmin[rt] = a[rank[l]]; return; }
int m = l + r >> 1;
build(lson);
build(rson);
push_up(rt);
}
void update(int L, int R, int val, int l, int r, int rt) {
if (L <= l && r <= R) { col[rt] = vmin[rt] = val; return; }
push_down(rt);
int m = l + r >> 1;
if (L <= m) { update(L, R, val, lson); }
if (m < R) { update(L, R, val, rson); }
push_up(rt);
}
int query(int L, int R, int l, int r, int rt) {
if (L <= l && r <= R) { return vmin[rt]; }
push_down(rt);
int m = l + r >> 1;
int ret = INF;
if (L <= m) { ret = min(ret, query(L, R, lson)); }
if (m < R) { ret = min(ret, query(L, R, rson)); }
return ret;
}
void modify(int x, int y, int d) {
while (top[x] != top[y]) {
if (dep[top[x]] < dep[top[y]]) { swap(x, y); }
update(cid[top[x]], cid[x], d, 1, n, 1);
x = fa[top[x]][0];
}
if (dep[x] > dep[y]) { swap(x, y); }
update(cid[x], cid[y], d, 1, n, 1);
}
int query(int rt) {
if (rt == root) { return query(1, n, 1, n, 1); }
int pre = lca(root, rt);
if (pre != rt) { return query(cid[rt], cid[rt] + size[rt] - 1, 1, n, 1); }
int depth = dep[root] - dep[rt] - 1, tmp = root;
for (int i = maxd - 1; i >= 0; --i) {
if (depth & (1 << i)) { tmp = fa[tmp][i]; }
}
return min(query(1, cid[tmp] - 1, 1, n, 1), query(cid[tmp] + size[tmp], n, 1, n, 1));
}
int main() {
int m, u, v, opt, id;
while (~scanf("%d%d", &n, &m)) {
g.init();
for (int i = 1; i < n; ++i) {
scanf("%d%d", &u, &v);
g.add(u, v); g.add(v, u);
}
for (int i = 1; i <= n; ++i) {
scanf("%d", &a[i]);
}
split();
build(1, n, 1);
scanf("%d", &root);
while (m--) {
scanf("%d", &opt);
switch (opt) {
case 1: scanf("%d", &root); break;
case 2: scanf("%d%d%d", &u, &v, &id); modify(u, v, id); break;
case 3: scanf("%d", &id); printf("%d\n", query(id)); break;
}
}
}
}
//KD-Tree
//<2F><><EFBFBD><EFBFBD>ά<EFBFBD><CEAC><EFBFBD><EFBFBD>ά<EFBFBD><CEAC>K<EFBFBD><4B><EFBFBD><EFBFBD><EFBFBD>Ծ<EFBFBD><D4BE><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ.
//<2F><>ÿһά<D2BB><CEAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>ƽ<EFBFBD><C6BD><EFBFBD><EFBFBD><EFBFBD>пռ<D5BC><E4BBAE>, <20><><EFBFBD><EFBFBD>ȽϾ<C8BD><CFBE>ȵطָ<D8B7><D6B8>ڸ<EFBFBD><DAB8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,
//<2F><EFBFBD><E1B9B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD>ö<EFBFBD><C3B6><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD>߶<EFBFBD><DFB6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̬<EFBFBD>͹<EFBFBD><CDB9><EFBFBD><ECB7BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Щ<EFBFBD><D0A9><EFBFBD><EFBFBD>.
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>KD-Treeһ<65><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>O(logn)<29>ĵ<EFBFBD><C4B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20>Լ<EFBFBD>O(n^(1-1/D))<29><>ѯ<EFBFBD>ʲ<EFBFBD><CAB2><EFBFBD>, <20><><EFBFBD><EFBFBD>D<EFBFBD><44>ά<EFBFBD><CEAC>, <20>ɼ<EFBFBD>ά<EFBFBD><CEAC>Խ<EFBFBD><D4BD>KD-TreeԽ<65><D4BD>
//ѯ<>ʾ<EFBFBD><CABE><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰK<C7B0><4B><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD>ȶ<EFBFBD><C8B6>н<EFBFBD><D0BD><EFBFBD>ѯ<EFBFBD><D1AF>ʱ<EFBFBD><CAB1>ά<EFBFBD><CEAC>
//HDU4347 O(n) <20><>֧<EFBFBD>ֵ<EFBFBD><D6B5>IJ<EFBFBD><C4B2><EFBFBD><EFBFBD><EFBFBD>ɾ<EFBFBD><C9BE>
const int N = 50005;
const int INF = ~0U >> 1;
const int DIM = 5;
#define lson l,m-1,dep+1
#define rson m+1,r,dep+1
int cur, K;
struct point {
int x[DIM];
bool operator<(const point &oth)const { return x[cur] < oth.x[cur]; }
void output() {
for (int i = 0; i < K; ++i) {
printf("%d%c", x[i], i < K - 1 ? ' ' : '\n');
}
}
} vec[N], origin[N], pt, ans[10];
inline int sqr(int x) { return x * x; }
int dist(const point &a, const point &b) {
int ret = 0;
for (int i = 0; i < K; ++i) { ret += sqr(a.x[i] - b.x[i]); }
return ret;
}
void build(int l, int r, int dep = 0) {
if (l >= r) { return; }
int m = l + r >> 1;
cur = dep % K;
nth_element(vec + l, vec + m, vec + r + 1);
build(lson);
build(rson);
}
priority_queue<pair<int, point>> pq;
void query(const point &x, int k, int l, int r, int dep = 0) {
if (l > r) { return; }
int m = l + r >> 1, cur = dep % K;
pair<int, point> tmp(dist(x, vec[m]), vec[m]);
if (pq.size() < k) {
pq.push(tmp);
} else if (pq.top().first > tmp.first) {
pq.pop(); pq.push(tmp);
}
if (x.x[cur] < vec[m].x[cur]) {
query(x, k, lson);
if (pq.top().first > sqr(x.x[cur] - vec[m].x[cur])) { query(x, k, rson); }
} else {
query(x, k, rson);
if (pq.top().first > sqr(x.x[cur] - vec[m].x[cur])) { query(x, k, lson); }
}
}
int main() {
int n, t, m;
while (~scanf("%d%d", &n, &K)) {
for (int i = 1; i <= n; ++i) {
for (int j = 0; j < K; ++j) {
scanf("%d", &origin[i].x[j]);
}
vec[i] = origin[i];
}
build(1, n);
scanf("%d", &t);
while (t--) {
for (int i = 0; i < K; ++i) {
scanf("%d", &pt.x[i]);
}
scanf("%d", &m);
query(pt, m, 1, n);
for (int i = 0; i < m; ++i) {
ans[i] = pq.top().second; pq.pop();
}
printf("the closest %d points are:\n", m);
for (int i = m - 1; i >= 0; --i) { ans[i].output(); }
}
}
}
//֧<>ֵ<EFBFBD><D6B5>IJ<EFBFBD><C4B2><EFBFBD><EFBFBD><EFBFBD>ɾ<EFBFBD><C9BE>
#define lson kdt[rt].ls,dep+1
#define rson kdt[rt].rs,dep+1
struct kdnode {
int ls, rs, x[DIM]; bool flag; //ɾ<><C9BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
} kdt[N];
inline ll sqr(int x) { return (ll)x * x; }
ll dist(const kdnode &a, const kdnode &b) {
ll ret = 0;
for (int i = 0; i < DIM; ++i) { ret += sqr(a.x[i] - b.x[i]); }
return ret;
}
int root, tot;
void init() { tot = 0; root = -1; }
int add(int pt[]) {
kdt[tot].flag = false;
kdt[tot].ls = kdt[tot].rs = -1;
for (int i = 0; i < DIM; ++i) { kdt[tot].x[i] = pt[i]; }
return tot++;
}
void insert(int pt[], int rt, int dep = 0) {
dep %= DIM;
if (pt[dep] < kdt[rt].x[dep]) {
if (!~kdt[rt].ls) { kdt[rt].ls = add(pt); }
else { insert(pt, lson); }
} else {
if (!~kdt[rt].rs) { kdt[rt].rs = add(pt); }
else { insert(pt, rson); }
}
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
ll query(const kdnode &pt, int rt, int dep = 0) {
if (!~rt) { return INF; }
dep %= DIM;
ll ret = INF, tmp = sqr(kdt[rt].x[dep] - pt.x[dep]);
if (!kdt[rt].flag) { ret = dist(kdt[rt], pt); }
if (pt.x[dep] <= kdt[rt].x[dep]) {
ret = min(ret, query(pt, lson));
if (tmp < ret) { ret = min(ret, query(pt, rson)); }
}
if (pt.x[dep] >= kdt[rt].x[dep]) {
ret = min(ret, query(pt, rson));
if (tmp < ret) { ret = min(ret, query(pt, lson)); }
}
return ret;
}
//<2F><>ѯ<EFBFBD><D1AF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD><D0B6>ٸ<EFBFBD><D9B8><EFBFBD>
int query(int pt1[], int pt2[], int rt, int dep = 0) {
if (!~rt) { return 0; }
dep %= DIM;
int ret = 0, cur;
for (cur = 0; cur < DIM; ++cur) {
if (kdt[rt].x[cur] < pt1[cur] || kdt[rt].x[cur] > pt2[cur]) { break; }
}
if (cur == DIM) { ++ret; }
if (pt2[dep] < kdt[rt].x[dep]) {
ret += query(pt1, pt2, lson);
} else if (pt1[dep] >= kdt[rt].x[dep]) {
ret += query(pt1, pt2, rson);
} else {
ret += query(pt1, pt2, lson);
ret += query(pt1, pt2, rson);
}
return ret;
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
int part[20][N]; //<2F><>ʾÿ<CABE><C3BF>ÿ<EFBFBD><C3BF>λ<EFBFBD>õ<EFBFBD>ֵ
int sorted[N]; //<2F>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>õ<EFBFBD><C3B5><EFBFBD>
int tol[20][N]; //tol[p][i] <20><>ʾ<EFBFBD><CABE>i<EFBFBD><69><EFBFBD><EFBFBD>1<EFBFBD><31>i<EFBFBD><69><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void build(int l, int r, int dep) {
if (l == r) { return; }
int m = l + r >> 1, cnt = m - l + 1; //<2F><>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD>м<EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD>ұ<EFBFBD><D2B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ߵĸ<DFB5><C4B8><EFBFBD>
for (int i = l; i <= r; ++i) {
if (part[dep][i] < sorted[m]) { --cnt; }
}
int lpos = l, rpos = m + 1;
for (int i = l; i <= r; ++i) {
if (part[dep][i] < sorted[m]) {
part[dep + 1][lpos++] = part[dep][i];
} else if (part[dep][i] == sorted[m] && cnt > 0) {
part[dep + 1][lpos++] = part[dep][i];
--cnt;
} else {
part[dep + 1][rpos++] = part[dep][i];
}
tol[dep][i] = tol[dep][l - 1] + lpos - l;
}
build(l, m, dep + 1);
build(m + 1, r, dep + 1);
}
//<2F><><EFBFBD>߲<EFBFBD>ѯ<EFBFBD><D1AF><EFBFBD><EFBFBD><EFBFBD><EFBFBD>k<EFBFBD><6B><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, [L, R]<5D><>Ҫ<EFBFBD><D2AA>ѯ<EFBFBD><D1AF>С<EFBFBD><D0A1><EFBFBD><EFBFBD>, [l, r]<5D>Ǵ<EFBFBD><C7B4><EFBFBD><EFBFBD><EFBFBD>
int query(int L, int R, int k, int l, int r, int dep) {
if (L == R) { return part[dep][L]; }
int m = l + r >> 1, cnt = tol[dep][R] - tol[dep][L - 1];
if (cnt >= k) {
int tl = l + tol[dep][L - 1] - tol[dep][l - 1], tr = tl + cnt - 1;
return query(tl, tr, k, l, m, dep + 1);
} else {
int tr = R + tol[dep][r] - tol[dep][R], tl = tr - (R - L - cnt);
return query(tl, tr, k - cnt, m + 1, r, dep + 1);
}
}
//<2F><>ƫ<EFBFBD><C6AB>
//<2F>ɲ<EFBFBD><C9B2>ѵ<EFBFBD>һ<EFBFBD><D2BB>ʵ<EFBFBD><CAB5>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>O(logn)<29><>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>ʵ<EFBFBD>ֶѵ<D6B6>push<73><68>pop<6F><70><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѵĺϲ<C4BA><CFB2><EFBFBD><EFBFBD><EFBFBD>, <20>Լ<EFBFBD>O(1)ʱ<><CAB1><EFBFBD><EFBFBD>ȡ<EFBFBD>Ѷ<EFBFBD><D1B6><EFBFBD><EFBFBD><EFBFBD>
int val[N], ls[N], rs[N], dep[N], fa[N];
void init(int n) {
for (int i = 1; i <= n; ++i) {
scanf("%d", &val[i]); ls[i] = rs[i] = dep[i] = 0; fa[i] = i;
}
}
int find(int x) { return x == fa[x] ? x : fa[x] = findfa(fa[x]); }
int merge(int x, int y) {
if (!x || !y) { return x | y; }
if (val[x] < val[y]) { swap(x, y); }
rs[x] = merge(rs[x], y); fa[rs[x]] = x;
if (dep[ls[x]] < dep[rs[x]]) { swap(ls[x], rs[x]); }
dep[x] = dep[rs[x]] + 1;
return x;
}
int push(int x, int y) { return merge(x, y); }
int pop(int x) {
int a = ls[x], b = rs[x];
ls[x] = rs[x] = dep[x] = 0;
fa[x] = x; fa[a] = a; fa[b] = b;
return merge(a, b);
}
//POJ 2201
int main() {
int n, m, x, y;
while (~scanf("%d", &n)) {
init(n);
scanf("%d", &m);
while (m--) {
scanf("%d%d", &x, &y);
int a = find(x), b = find(y);
if (a == b) {
puts("-1");
} else {
val[a] >>= 1; val[b] >>= 1;
a = push(pop(a), a); b = push(pop(b), b);
printf("%d\n", val[merge(a, b)]);
}
}
}
}
//<2F>ѿ<EFBFBD><D1BF><EFBFBD><EFBFBD><EFBFBD>
//<2F><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>ֵ<EFBFBD>Ե<EFBFBD><D4B5><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, ֵ<><D6B5>ֵ֮<D6B5><EFBFBD><E4BBA5><EFBFBD><EFBFBD>ͬʱ, <20><><EFBFBD>ǿ<EFBFBD><C7BF><EFBFBD>Ψһ<CEA8>ع<EFBFBD><D8B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD>ö<EFBFBD><C3B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//key<65><79><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>; <20><><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD>value<75><65><EFBFBD><EFBFBD><EFBFBD>ӽڵ<D3BD><DAB5><EFBFBD>value, <20><><EFBFBD><EFBFBD><EFBFBD>ѵ<EFBFBD><D1B5><EFBFBD><EFBFBD><EFBFBD>.
//һ<><D2BB><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD>еĵѿ<C4B5><D1BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>O(n)ʱ<><CAB1><EFBFBD>ڹ<EFBFBD><DAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//POJ2201
const int N = 50005;
int idx[N], n;
struct Cartesian_Tree {
int root, key[N], val[N], ch[N][2], pre[N];
void init() {
for (int i = 1; i <= n; ++i) {
scanf("%d%d", &key[i], &val[i]);
ch[i][0] = ch[i][1] = pre[i] = 0;
}
}
void build() {
static int st[N];
int top = -1;
for (int i = 1; i <= n; ++i) {
int k = top;
while (k >= 0 && val[st[k]] > val[idx[i]]) {
--k;
}
if (~k) {
pre[idx[i]] = st[k];
ch[st[k]][1] = idx[i];
}
if (k < top) {
pre[st[k + 1]] = idx[i];
ch[idx[i]][0] = st[k + 1];
}
st[++k] = idx[i];
top = k;
}
root = st[0];
}
} ct;
bool cmp(int x, int y) {
return ct.key[x] < ct.key[y];
}
int main() {
while (~scanf("%d", &n)) {
ct.init();
for (int i = 1; i <= n; ++i) { idx[i] = i; }
sort(idx + 1, idx + n + 1, cmp);
ct.build();
puts("YES");
for (int i = 1; i <= n; ++i) {
printf("%d %d %d\n", ct.pre[i], ct.ch[i][0], ct.ch[i][1]);
}
}
}