voidrotate(int x){ /** 旋转 x 节点: * 如果 x 是左儿子就右旋,如果x是右儿子就左旋 */ int f = fa(x), ff = fa(f), k = ident(x); connect(spl[x].ch[k^1], f, k); // 1 connect(x, ff, ident(f)); // 2 (2,3)顺序不能反,因为2要用到 ident(f) 不能先把f 更新了 connect(f, x, k^1); // 3 update(f); update(x); }
voidsplay(int x, int top){ /** 旋转x到to位置 */ int to = fa(top); // 找到那个位置的爸爸 while (fa(x) != to) { // 只要我的爸爸不是 to的爸爸,就要一直转 if (fa(fa(x)) == to) rotate(x); // 只差一步就到了 elseif (ident(x) == ident(fa(x))) { rotate(fa(x)); rotate(x); } // 链情况 elserotate(x), rotate(x); } }
voidins(int v){ /** 插入一个结点,值为 v */ int x = root; if (!x) { root = newnode(v, 0); return; } while (true) { if (spl[x].v == v) { spl[x].rep++; splay(x, root); return; } // 值重复情况 int nxt = v < spl[x].v ? 0 : 1; // 去左子树还是右子树 if (!child) { child = newnode(v, x); splay(child, root); return; } // 跟新根 x = child; } }
intfind(int v){ /** 查找值 v 是否存在,存在返回结点编号 */ int x = root; while (true) { if (!x) return0; // 找不到的情况 if (spl[x].v == v) { splay(x, root); return x; } int nxt = v < spl[x].v ? 0 : 1; x = child; } }
voiddel(int v){ /** 删除一个结点 */ int x = find(v); if (!x) return; // 删除结点不存在 if (spl[x].rep > 1) { spl[x].rep--; spl[x].sz--; return; } // 删除重复数据 elseif (!ls(x) && !rs(x)) { root = 0; return; } // 只剩一个点 elseif (!ls(x)) { root = rs(x); fa(rs(x)) = 0; return; } // 没有前驱 else { // 有前驱 int u = ls(x); while (rs(u)) u = rs(u); // 找到前驱 splay(u, ls(x)); // 转到x的左儿子 connect(rs(x), u, 1); connect(u, 0, 1); // 变成根 update(u); // 重建父子关系后要更新 } }
intrk(int v){ /** 查询一个数的排名 */ int p = find(v); return spl[ls(p)].sz + 1; }
template<typename T> T kth(int k){ /** 查询排名为 k 的数 */ int x = root; int ret = 0; while (true) { int used = spl[x].sz - spl[rs(x)].sz; if (spl[ls(x)].sz < k && k <= used) { splay(x, root); return spl[x].v; } if (k < used) x = ls(x); else x = rs(x), k -= used; } }
voidprint(int x){ if (!x) return; if (spl[x].ch[0]) print(spl[x].ch[0]); cout << spl[x].v << " "; if (spl[x].ch[1]) print(spl[x].ch[1]); }
template<typename T> T lower(int v){ /** 查找 v 的前驱 * 先给答案赋个最小值,然后不断提升它 */ int x = root; T ret = INT_MIN; while (x) { if (spl[x].v < v && spl[x].v > ret) ret = spl[x].v; // 取最大值 int nxt = v <= spl[x].v ? 0 : 1; // 这里是 <= x = child; } return ret; }
template<typename T> T upper(int v){ /** 查找 v 的后继 */ int x = root; T ret = INT_MAX; while (x) { if (spl[x].v > v && spl[x].v < ret) ret = spl[x].v; int nxt = v < spl[x].v ? 0 : 1; // 这里 < x = child; } return ret; }
intmain(){ freopen("d.txt","r",stdin); ios_base::sync_with_stdio(0); cin.tie(0); cin >> n; for (int i = 1;i <= n; ++i) { int x, op; cin >> op >> x; if (op == 1) ins(x); if (op == 2) del(x); if (op == 3) cout << rk(x) << endl; if (op == 4) cout << kth<int>(x) << endl; if (op == 5) cout << lower<int>(x) << endl; if (op == 6) cout << upper<int>(x) << endl; } return0; }
#define mid ((l+r)>>1) #define ls (o<<1) #define rs (o<<1|1)
voidinsert(int o, int l, int r, int x){ if (l == r) sumv[o]++; else { if (x <= mid) insert(ls, l, mid, x); elseinsert(rs, mid+1, r, x); sumv[o] = sumv[ls] + sumv[rs]; } }
ll query(int o, int l, int r, int ql, int qr){ if (l > r) return0; if (ql <= l && r <= qr) return sumv[o]; else { ll ret = 0; if (ql <= mid) ret += query(ls, l, mid, ql, qr); if (qr > mid) ret += query(rs, mid+1, r, ql, qr); return ret; } }
intmain(){ ios_base::sync_with_stdio(0); cin.tie(0); cin >> n; string s, res; vector<int> B(n); vector<int> cnt(26); vector<vector<int>> num(26, vector<int>()); cin >> s; res = s; reverse(res.begin(), res.end()); for (int i = 0;i < len(s); ++i) num[s[i] - 'a'].push_back(i); for (int c = 0;c < 26; ++c) { for (int i = 0;i < len(res); ++i) { if (res[i] == c + 'a') B[i] = num[c][cnt[c]++]; } } ll ans = 0; for (int i = 0;i < len(res); ++i) { ans += query(1, 0, n-1, B[i]+1, n-1); insert(1, 0, n-1, B[i]); } cout << ans << endl; return0; }
int n, m, tot; int ch[maxn*33][2], val[maxn*33]; ll sum[33][2]; vector<int> num[maxn*33]; int ans; ll anssum; voidinsert(int x, int ind){ int u = 0; for (int i = 31; i >= 0; --i) { bool nxt = (x & (1 << i)) > 0; if (!ch[u][nxt]) ch[u][nxt] = ++tot; u = ch[u][nxt]; num[u].push_back(ind); } val[u]++; }
voiddfs(int u, int pos){ if (sz(num[ch[u][0]]) && sz(num[ch[u][1]])) { ll iv = 0; for (auto x : num[ch[u][0]]) { ll k = lower_bound(num[ch[u][1]].begin(), num[ch[u][1]].end(), x) - num[ch[u][1]].begin() ; iv += k; } ll another = (ll)sz(num[ch[u][0]]) * sz(num[ch[u][1]]) - iv; sum[pos][0] += iv; sum[pos][1] += another; } if (sz(num[ch[u][0]])) dfs(ch[u][0], pos - 1); if (sz(num[ch[u][1]])) dfs(ch[u][1], pos - 1); }
intmain(){ ios_base::sync_with_stdio(0); cin.tie(0); cin >> n; for (int i = 1;i <= n; ++i) { int x; cin >> x; insert(x, i); } dfs(0, 31); for (int i = 31;i >= 0; --i) { if (sum[i][0] > sum[i][1]) { anssum += sum[i][1]; ans |= 1<<i; } else anssum += sum[i][0]; } cout << anssum << " " << ans << endl; return0; }